Please explain me the working of strtok()
function.The manual says it breaks the string into tokens. I am unable to understand from the manual what actually it does.
I added watches on str
and *pch
to check its working, when the first while loop occurred, the contents of str
were only "this". How did the output shown below printed on the screen?
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Output:
Splitting string "- This, a sample string." into tokens: This a sample string
For those who are still having hard time understanding this
strtok()
function, take a look at this pythontutor example, it is a great tool to visualize your C (or C++, Python ...) code.In case the link got broken, paste in:
Credits go to Anders K.
strtok modifies its input string. It places null characters ('\0') in it so that it will return bits of the original string as tokens. In fact strtok does not allocate memory. You may understand it better if you draw the string as a sequence of boxes.
strtok
doesn't change the parameter itself (str
). It stores that pointer (in a local static variable). It can then change what that parameter points to in subsequent calls without having the parameter passed back. (And it can advance that pointer it has kept however it needs to perform its operations.)From the POSIX
strtok
page:There is a thread-safe variant (
strtok_r
) that doesn't do this type of magic.To understand how
strtok()
works, one first need to know what a static variable is. This link explains it quite well....The key to the operation of
strtok()
is preserving the location of the last seperator between seccessive calls (that's whystrtok()
continues to parse the very original string that is passed to it when it is invoked with anull pointer
in successive calls)..Have a look at my own
strtok()
implementation, calledzStrtok()
, which has a sligtly different functionality than the one provided bystrtok()
And here is an example usage
The code is from a string processing library I maintain on Github, called zString. Have a look at the code, or even contribute :) https://github.com/fnoyanisi/zString
the strtok runtime function works like this
the first time you call strtok you provide a string that you want to tokenize
in the above string space seems to be a good delimiter between words so lets use that:
what happens now is that 's' is searched until the space character is found, the first token is returned ('this') and p points to that token (string)
in order to get next token and to continue with the same string NULL is passed as first argument since strtok maintains a static pointer to your previous passed string:
p now points to 'is'
and so on until no more spaces can be found, then the last string is returned as the last token 'string'.
more conveniently you could write it like this instead to print out all tokens:
EDIT:
If you want to store the returned values from
strtok
you need to copy the token to another buffer e.g.strdup(p);
since the original string (pointed to by the static pointer insidestrtok
) is modified between iterations in order to return the token.strtok
maintains a static, internal reference pointing to the next available token in the string; if you pass it a NULL pointer, it will work from that internal reference.This is the reason
strtok
isn't re-entrant; as soon as you pass it a new pointer, that old internal reference gets clobbered.