7

To loop over a string str I used:

for (tok = strtok(str, ";"); tok && *tok; tok = strtok(NULL, ";"))  
{  
   //do stuff  
}

I would like to understand how this loop works. It seems to me:

(1) tok = strtok(str, ";"); //initialization of tok with the first token in str    
(2) tok = strtok(NULL, ";"); // go to the next token in str? how does this work? 
(3) tok && *tok;  //this stops the loop when tok =NULL or *tok=NULL 

I would appreciate your help!

loisir2022
  • 163
  • 2
  • 11
  • 4
    You're right on all the three counts :) – Sergey Kalinichenko Jun 27 '13 at 23:55
  • Take a look at the **Related** questions for more details about how `strtok()` works. Especially http://stackoverflow.com/questions/3889992/please-help-in-strtok?rq=1 – Barmar Jun 27 '13 at 23:57
  • 1
    The `*tok` test isn't part of the standard strtok idiom. It looks like it wants to stop early on an empty field, but it won't work because strtok skips empty fields. –  Jun 28 '13 at 00:00
  • @WumpusQ.Wumbley So *tok is useless it should be removed? Thanks – loisir2022 Jun 28 '13 at 00:04
  • It's not doing anything. Removing `&& *tok` will not change the behavior. If you want to detect empty fields, you can't use strtok. –  Jun 28 '13 at 00:18

4 Answers4

4

Here's a sample strtok implementation: http://bxr.su/o/lib/libc/string/strtok.c#strtok

As you see in the code, it uses a static character pointer internally (pretty much every version I've seen store a pointer, either as a global variable or as a static variable as in the case above). This version calls the reentrant strtok_r (and the side effect of the line if (s == NULL && (s = *last) == NULL) is to use the last pointer if NULL is passed)

cnst
  • 25,870
  • 6
  • 90
  • 122
SheetJS
  • 22,470
  • 12
  • 65
  • 75
1

(2) tok = strtok(NULL, ";"); // go to the next token in str? how does this work?

That's exactly how strtok() works. By sending NULL as the first parameter, you signal that strtok() should continue with the string which was sent to it during the last call. If you want to know the exact implementation details, you will need to look at the source code for strtok(). Most likely it uses a static local variable.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • 1
    The way it works is indeed that it squirrels away the first argument from the initial call in a private variable. – Jim Balter Jun 28 '13 at 00:05
  • Actually, I should have said that squirrels away the end of the first token / start of the next token, and updates that with each call. – Jim Balter Jun 28 '13 at 00:11
-1

if you read the manpages for strtok it states

The strtok() function parses a string into a sequence of tokens. On the first call to strtok() the string to be parsed should be specified in str. In each subsequent call that should parse the same string, str should be NULL.

DevZer0
  • 13,433
  • 7
  • 27
  • 51
-1

You can find more about strtok here. It has some examples of how to use it.

Quoting from the link, the str parameter in strtok(str, delim):

Notice that the contents of this string are modified and broken into smaller strings (tokens). Alternativelly, a null pointer may be specified, in which case the function continues scanning where a previous successful call to the function ended.

Your 3 guesses are correct.

jh314
  • 27,144
  • 16
  • 62
  • 82
  • I'm not the downvoter, but it just duplicates what the OP wrote, except for "how does this work?", which it doesn't answer. – Jim Balter Jun 28 '13 at 00:06