2014-03-29 137 views
2

我想从一个字符串获得令牌,然后得到令牌的子令牌,这样的短节目:的strtok()不处理第二令牌

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void f(char *bak) 
{ 
    char *token, *delim = "."; 

    token = strtok(bak, delim); 
    while(token) { 
     printf("f(): token: %s\n", token); 
     token = strtok(NULL, delim); 
    } 
} 

int main(void) 
{ 
    char str[] = "a.1.2 x.y"; 
    char *token, *delim = " \t\n\r"; 

    token = strtok(str, delim); 
    while(token) { 
     printf("main: token: %s\n", token); 

     char bak[100]; 
     strncpy(bak, token, sizeof(bak)); 
     f(bak); 

     token = strtok(NULL, delim); 
    } 

    return 0; 
} 

但是,它只能显示第一令牌(“a.1.2”),而不是第二个:

main: token: a.1.2 
f(): token: a 
f(): token: 1 
f(): token: 2 

这是怎么发生的?谢谢。

+0

使用'const char *'作为字符串文字。更好的是,'std :: string'。 – chris

+0

C或C++?选择一个_.... –

回答

4

strtok()一次只能处理一个字符串的标记(它依赖于内部静态变量来维持连续调用之间的状态,不可重入和非线程安全)。在f()strtok(bak, delim)呼叫无效在main()上一次调用​​,所以当执行流从f()返回到main()和来调用strtok(NULL, delim),它实际上仍对"a.1.2"标记化(这是在f()已经完成工作),因此token被赋予一个空指针值,该指针终止循环。

+0

谢谢。我改为strtok_r(),它似乎工作。 – user2847598

+0

@ user2847598:是的,'strtok_r()'是'strtok()'的可重入版本。 – neverhoodboy

0

strtok()一次处理一个字符串的一个标记。因此,您可以使用strtok_r()函数来为一个字符串一次处理多个标记。

SO,它是strtok()函数的递归函数。