2014-04-29 80 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);