2014-03-29 103 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()函數的遞歸函數。