Reputation: 1886
strtok wont work correctly when using char *str as the first parameter (not the delimiters string).
Does it have something to do with the area that allocates strings in that notation? (which as far as i know, is a read-only area).
thanks in advance
example:
//char* str ="- This, a sample string."; // <---doesn't work
char str[] ="- This, a sample string."; // <---works
char delims[] = " ";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,delims);
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, delims);
}
return 0;
Upvotes: 4
Views: 3727
Reputation: 2181
here is a code, all aspect should be pationed.
give me a hint if i forgot anything
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define WHITE " \t\n" // white space, tab and newline for tokenizing arguments
#define MAXARGC 50 // max number of arguments in buf
void handlecommand(int argc, char *argv[])
{
// do some handle code, in this example, just print the arguments
for(int i = 0; i < argc; i++)
printf("argv[%d]='%s'\n", i, argv[i]);
}
void parsecommand(char * cmdstr)
{
char *cmdstrdup = strdup(cmdstr);
if(cmdstrdup == NULL)
//insuficient memory, do some errorhandling.
return;
char *saveptr;
char *ptr;
char *argv[MAXARGC];
int argc;
if((ptr = strtok_r(cmdstrdup, WHITE, &saveptr)) == NULL)
{
printf("%s\n", "no args given");
return;
}
argv[argc = 0] = cmdstrdup;
while(ptr != NULL) {
ptr = strtok_r(NULL, WHITE, &saveptr);
if(++argc >= MAXARGC-1) // -1 for room for NULL at the end
break;
argv[argc] = ptr;
}
// handle command before free
handlecommand(argc, argv);
// free cmdstrdup, cuz strdup does malloc inside
free(cmdstrdup);
}
int main(int argc, char const *argv[])
{
parsecommand("command arg1 arg2 arg3\targ4\narg5 arg6 arg7");
return 0;
}
Result
argv[0]='command'
argv[1]='arg1'
argv[2]='arg2'
argv[3]='arg3'
argv[4]='arg4'
argv[5]='arg5'
argv[6]='arg6'
argv[7]='arg7'
Upvotes: 0
Reputation: 455272
strtok
modifies its 1st argument.
In your case 1 the argument to strtok
is a string literal
which cannot be modified and hence strtok
fails . But in case 2 the argument is a modifiable char
array which strtok
modifies and breaks into smaller strings.
Upvotes: 3
Reputation:
In the first case, you pass a string literal to strtok(). As strtok() modifies this string, and as string literals cannot legally be modified, you end up with undefined behaviour. In the second case, the compiler copies the string into the array. Array contents can be modified, so this code is OK.
Upvotes: 7