So I'm new to C and the whole string manipulation thing, but I can't seem to get strtok() to work. It seems everywhere everyone has the same template for strtok being:
char* tok = strtok(source,delim);
do
{
{code}
tok=strtok(NULL,delim);
}while(tok!=NULL);
So I try to do this with the delimiter being the space key, and it seems that strtok() no only reads NULL after the first run (the first entry into the while/do-while) no matter how big the string, but it also seems to wreck the source, turning the source string into the same thing as tok.
Here is a snippet of my code:
char* str;
scanf("%ms",&str);
char* copy = malloc(sizeof(str));
strcpy(copy,str);
char* tok = strtok(copy," ");
if(strcasecmp(tok,"insert"))
{
printf(str);
printf(copy);
printf(tok);
}
Then, here is some output for the input "insert a b c d e f g"
aaabbbcccdddeeefffggg
"Insert" seems to disappear completely, which I think is the fault of strcasecmp(). Also, I would like to note that I realize strcasecmp() seems to all-lower-case my source string, and I do not mind. Anyhoo, input "insert insert insert" yields absolutely nothing in output. It's as if those functions just eat up the word "insert" no matter how many times it is present. I may* end up just using some of the C functions that read the string char by char but I would like to avoid this if possible. Thanks a million guys, i appreciate the help.
str
withchar* copy = strdup(str);
instead of usingmalloc
incorrectly, and forgetting to actually perform the copy. – patprintf
with an unknown string as the first argument. The first argument is a format string that uses%
delimited format specifiers to interpret subsequent arguments. If any of your unknown strings contain a%
, bad things will happen. Useputs(str)
,fputs(str, stdout)
, orprintf("%s", str)
instead. – patstrtok
mutates the string it is scanning by replacing the delimiters withNUL
terminators. If you printcopy
, after runningstrtok
on it, you will only ever see the first token, since theNUL
terminator is never removed after being inserted. However, each call tostrtok
with aNULL
first argument will pick up where the previous call left off (just after the delimiter that is now aNUL
), and scan forward from there, returning the token that started at that position. – patstrcmp
andstrcasecmp
return the lexicographic difference between the two strings. When the strings are equal, it returns0
, which is a false value in C. If you want the body of theif
to execute whentok
is equal to"insert"
, then you should explicitly check the return value for0
. i.e.if(strcasecmp(tok, "insert") == 0)
. – pat%s
scanf
format specifier reads a whitespace delimited string, so you're only going to get"insert"
in your buffer. The rest of the input is still going to be sitting in the stdin buffer. – pat