I am trying to print the tokens of the command line argument using a function that uses the strtok function. The point is that the return statement does not recognize the pointer returned.
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
#include <malloc.h>
#include <Windows.h>
#include<string>
using namespace std;
char **makeargv(char *s);
int main()
{
int i;
char **myargv;
char mytest[] = "This is a test";
if((myargv = makeargv(mytest)) == NULL)
fprintf(stderr,"Failed to construct an argument array\n");
else
for (i=0;myargv[i]!=NULL;i++)
printf("%d:%s\n",i,myargv[i]);
system("pause");
return 0;
}
char **makeargv(char *mytest)
{
char *pch;
printf("Splitting string \%s\ into tokens:\n",mytest);
pch = strtok(mytest," ");
while(pch != NULL)
{
printf("%s\n",pch);
pch = strtok(NULL," ");
}
pch = strtok(mytest," ");
char *s = pch;
return &s;
}
char *s = pch;
s
is a pointer to character, but in return **s;
statement, you are dereferencing twice, which is wrong. Your intended usage is
return &s;
this will return a pointer to pointer to character ( char**
).
But your overall program is ill-defined in terms of pointer usage. For example, you are returning pointer to a local variable on the stack, which will be destroyed once the method returns, and accessing it in the caller is UB .
And before returning pch
will be NULL
, so will s
, so basically you are taking and returning address of a NULL pointer .
Define char *myargv[MAXARGV]
, and pass that into your makeargv
function, and store pch
in that. Return number of arguments found.
This will always make pch point to NULL after the loop since that is your ending condition.
while(pch != NULL)
{
printf("%s\n",pch);
pch = strtok(NULL," ");
}
char *s = pch; // pch is NULL
if you want to return the last token you could just do a search for last space manually
also as Rakibul already mentioned you should not dereference the string twice, what you need to return is the address of the string ie pch itself.
if you have strrev on your system you could write something like
strrev( mytest ); // reverse string
char* pch = strtok( mytest, " " ); // extract token
if ( pch != NULL )
{
puts( strrev(pch) ); // back to original
}
You wrote
I have made a small change to the function but i am getting bad pointer exception error
char **makeargv(char *mytest)
{
char *pch;
printf("Splitting string %s\ into tokens:\n",mytest);
pch = strtok(mytest," ");
while(pch != NULL)
{
printf("%s\n",pch);
pch = strtok(NULL," ");
}
pch = strtok(mytest," ");
char *s = pch;
return &s;
}
You still try to return the address of the pointer as well you seem not know that strtok modifies its argument, the original string is modified when you pass it to the strtok function.
Instead try something like this
char **makeargv(char *mytest)
{
// setup an array of pointers to strings, 20 is an arbitrary value
const int maxtokens = 20;
char**tokens = malloc( sizeof(char*) * maxtokens );
for ( int i = 0; i < maxtokens; ++i )
{
tokens[i] = NULL;
}
printf("Splitting string %s\ into tokens:\n",mytest);
char *pch = strtok(mytest," ");
int found = 0;
// the maxtokens - 1 will ensure that at least one pointer is null
// in the array
while(pch != NULL && found < maxtokens - 1)
{
printf("%s\n",pch);
tokens[found++] = strdup(pch); // allocate and copy token
pch = strtok(NULL," ");
}
return tokens;
}
now you get an array with the tokens
char arg[] = "this is a test";
char** tokens = makeargv(arg);
int i = 0;
for (i = 0; tokens[i] != NULL; ++i)
puts( tokens[i] );
don't forget to free the memory later
for (i = 0; tokens[i] != NULL; ++i)
free( tokens[i] );
free( tokens );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.