字符串标记问题

时间:2014-04-29 13:00:52

标签: c string tokenize

我有这个字符串:"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)

怎么了?

3 个答案:

答案 0 :(得分: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]);
}

答案 1 :(得分:0)

请查看strtok的文档:

  

对strtok函数的一系列调用将s1指向的字符串分解为a   标记序列,每个标记由指向的字符串中的字符分隔   由s2。序列中的第一个调用具有非null的第一个参数;随后的电话   sequence具有null第一个参数。 s2指向的分隔符字符串可以是   与来电不同。
  序列中的第一个调用将搜索s1指向的字符串作为第一个字符   它不包含在s2指向的当前分隔符字符串中。如果没有这样的角色   找到,然后s1和strtok函数指向的字符串中没有标记   返回一个空指针。如果找到这样的字符,则它是第一个标记的开头   然后strtok函数从那里搜索包含在中的字符   当前分隔符字符串如果找不到这样的字符,则当前令牌扩展到   s1指向的字符串的结尾,随后对标记的搜索将返回null   指针。如果找到这样的字符,它将被空字符覆盖,这是一个空字符   终止当前令牌。 strtok函数保存指向以下内容的指针   字符,从中开始下一次搜索令牌。

简而言之,strtok搜索序列开头不在分隔符中的第一个字符,然后搜索序列结尾的分隔符中的第一个字符。
这意味着您最近两次拨打strtok的电话会回复NULL,因此printf - 来电是未定义的行为,可能会发生任何事情。

更好地使用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以避免数据争用并使您的代码可重入。

答案 2 :(得分: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);