2014-04-29 119 views
2

我有這個字符串:"Alaska:(3,4)"和我想要"Alaska","3","4"子字符串。但我有一個問題。字符串標記問題

cityName = strtok(str , ":"); 
printf("name : %s\n",cityName); 
temp = strtok(NULL , "("); 
printf("%s\n",temp); 
temp = strtok(NULL , ","); 
printf("%s\n",temp); 
temp = strtok(NULL, ")"); 
printf("%s\n",temp); 

對於這個代碼我得到這樣的輸出:

name : Alaska 
3,4) 
(null) 
(null) 

有什麼不對?

+1

+1第一次問題清楚地說明問題,提出的代碼,輸入,輸出和所需的輸出。可悲的是很少見。 – chux

回答

1

您的實現無法正常工作的原因是因爲strtok在第二次調用後已識別該字符串爲完全解析(因爲在第一個標記之前未找到任何內容)。您需要在第二次調用後重新開始解析。

void bar(char * str) { 
    char * cityName, *temp; 
    cityName = strtok(str , ":"); 
    printf("name : %s\n",cityName); 
    temp = strtok(NULL , "("); 
    printf("%s\n",temp); 
    temp = strtok(temp , ","); // restart parsing here 
    printf("%s\n",temp); 
    temp = strtok(NULL, ")"); 
    printf("%s\n",temp); 
} 

請注意strtok對輸入字符串是破壞性的,並且不是線程安全的。

您是否考慮過使用sscanf系列?如果您使用固定格式,使用起來會更容易一些。

void foo(char * str) { 
    char city[32], num[2][32]; 
    sscanf(str, "%[^:]:(%[^,],%[^)])", city, num[0], num[1]); 
    printf("%s\n%s\n%s\n", city, num[0], num[1]); 
} 
+0

這是如何回答這個問題的? – this

0

請大家看看文檔strtok

調用到strtok的功能序列打破了指向的字符串S1成標記 序列,其中每個分隔由s2指向 的字符串中的一個字符。序列中的第一個調用具有非空的第一個參數; 序列中的後續調用具有空的第一個參數。由s2指向的分隔符字符串可能是 ,與呼叫呼叫不同。
該序列中的第一個調用搜索s1指向的字符串,該字符串中第一個字符 未包含在s2指向的當前分隔符字符串中。如果找不到這樣的字符 ,那麼s1指向的字符串中沒有令牌,並且strtok函數 返回空指針。如果找到這樣的字符,它就是第一個標記的開始。
strtok函數然後從那裏搜索當前分隔符字符串中包含的字符。如果找不到這樣的字符,則當前令牌擴展到由s1指向的字符串的 末尾,並且隨後對令牌的搜索將返回空指針 。如果找到這樣的字符,它將被空字符覆蓋,該字符將終止當前令牌。 strtok函數會保存一個指向下面的 字符的指針,從該字符開始下一個令牌搜索。

總之,strtok搜索的第一個字符不是定界符的序列的開始,然後在分隔符的第一個字符的序列的結束。
這意味着您最後兩次致電strtok的電話會返回NULL,因此printf-calls爲未定義的行爲,則可能發生任何事情。

更好地使用sscanf或推出自己的解析器(可能不再需要)。

如果你想留在strtok,糾正你的分隔符,只試圖讓三個令牌:仍然

cityName = strtok(str , ":"); 
printf("name : %s\n",cityName); 
temp = strtok(NULL , "(,)"); 
printf("%s\n",temp); 
temp = strtok(NULL , "(,)"); 
printf("%s\n",temp); 

,至少考慮遷移到strtok_s,以避免數據爭,使您的代碼可再入。

0

strtok(3)不喜歡空分隔符。你有權訪問strsep(3)

char str[] = "Alaska:(3,4)"; 
char *p = str; 
char *temp; 
char *cityName = strsep(&p , ":"); 
printf("name : %s\n",cityName); 
temp = strsep(&p , "("); 
printf("%s\n",temp); 
temp = strsep(&p , ","); 
printf("%s\n",temp); 
temp = strsep(&p, ")"); 
printf("%s\n",temp);