C 为什么strtok总是找到模式&引用;?
在我的系统上,以下程序:C 为什么strtok总是找到模式&引用;?,c,strtok,C,Strtok,在我的系统上,以下程序: int main(){ char *strgptr; char buf[5] = {'b','a','a','a','\0'}; char *tmp = strtok_r(buf, ".", &strgptr); if(tmp != NULL){ printf("Found a . in baaa?\n"); printf("It wa
int main(){
char *strgptr;
char buf[5] = {'b','a','a','a','\0'};
char *tmp = strtok_r(buf, ".", &strgptr);
if(tmp != NULL){
printf("Found a . in baaa?\n");
printf("It was found starting at: %s\n", tmp);
}
else
printf("Everything is working.\n");
}
印刷品:
Found a . in baaa?
It was found starting at: baaa
但是,如果我将strtok_r中的“.”分隔符字符串替换为“a”,我会得到(如预期的那样):
但将“.”替换为buf中未出现的任何其他字符(例如“c”)会产生:
Found a . in baaa?
It was found starting at: baaa
正如所料,strtok_r的手册页上说:
The strtok() and strtok_r() functions return a pointer to the next token,
or NULL if there are no more tokens.
那么,当传递的字符串不包含任何有问题的标记时,strtok\u r为什么不能返回NULL呢?因为分隔符“在
buf
中找不到,您对strtok
的调用成功地返回指向您的第一个(也是唯一一个)标记的指针:“baaa”
如果未在buf
中找到,则对strtok
的调用将成功返回指向第一个(也是唯一一个)标记的指针:“baaa”
,因为未找到分隔符,所以返回整个字符串。它的作用就像字符串后面有一个不可见的分隔符。因为没有找到分隔符,所以返回整个字符串。它的作用就像字符串后面有一个不可见的分隔符。我想您实际上需要使用函数strstr()。strtok\u r用于拆分字符串,例如使用逗号或\n。我想您实际上需要使用函数strstr()。strtok\u r用于拆分字符串,例如使用逗号或\n。好的,这是有道理的,但为什么要这样设计?例如,在上面的代码中,我不能使用if(tmp!=buf),因为对于第一个令牌,它总是等于buf。因此,检查分隔符是否存在需要完全独立的操作。似乎是浪费,因为strtok在工作过程中无论如何都要检查它。它之所以这样设计是因为strtok
用于将字符串拆分为由分隔符分隔的标记。您的字符串由一个标记(不是无)组成,其方式与字符串“hello”包含一个单词(不是无)的方式相同。好的,这有一定的道理,但为什么它是这样设计的?例如,在上面的代码中,我不能使用if(tmp!=buf),因为对于第一个令牌,它总是等于buf。因此,检查分隔符是否存在需要完全独立的操作。似乎是浪费,因为strtok在工作过程中无论如何都要检查它。它之所以这样设计是因为strtok
用于将字符串拆分为由分隔符分隔的标记。您的字符串由一个标记(不是无)组成,就像字符串“hello”包含一个单词(不是无)一样。@JohnDoucette问得好。。。我想这不是很明显,尽管相反的结果(您预期的结果)对我来说也不明显。我的想法是,因为我必须有某种方式访问buf(将其传递给strtok调用),所以在调用strtok后返回指向buf的指针是没有意义的,因为如果不执行strcmp或类似操作,我就无法判断字符串是否包含分隔符。相反,如果返回NULL,我仍然有buf,但现在是一个O(1)操作来检查分隔符是否存在。我想我可以改为在strgptr上操作,但这是一个特定于实现的解决方案…@John:标准中记录了这一点:“strtok
函数然后从那里搜索包含在当前分隔符字符串中的字节。如果找不到这样的字节,则当前标记将扩展到s1指向的字符串的末尾。”. 我的系统上的手册页没有这样说——我个人认为它有缺陷,因为它描述了“后续令牌”是如何返回的,但实际上没有说明在没有分隔符的情况下“第一个令牌”是什么。@John:这是实施标准的人的一个常见爱好,以他们认为更简单的方式重新编写标准文本。在创建标准的快速参考指南方面,他们可能赢的比输的多,但往往不够精确,因此如果您对其行为感到惊讶或手册页含糊不清,您应该始终使用标准。在这种情况下,手册页是模糊的,但我不认为它明显是模糊的,我可以看到你是如何阅读它的。这是我不信任C标准函数手册页的原因。@Johnducette问得好。。。我想这不是很明显,尽管相反的结果(您预期的结果)对我来说也不明显。我的想法是,因为我必须有某种方式访问buf(将其传递给strtok调用),所以在调用strtok后返回指向buf的指针是没有意义的,因为如果不执行strcmp或类似操作,我就无法判断字符串是否包含分隔符。相反,如果返回NULL,我仍然有buf,但现在是一个O(1)操作来检查分隔符是否存在。我想我可以改为在strgptr上操作,但这是一个特定于实现的解决方案…@John:标准中记录了这一点:“strtok
函数然后从那里搜索包含在当前分隔符字符串中的字节。如果找不到这样的字节,则当前标记将扩展到s1指向的字符串的末尾。”. 我的系统上的手册页没有这样说——我个人认为它有缺陷,因为它描述了“后续令牌”是如何返回的,但实际上没有说明在没有分隔符的情况下“第一个令牌”是什么。@John:这是实施标准的人的一个常见爱好,以他们认为更简单的方式重新编写标准文本。在创建标准的快速参考指南方面,他们可能赢的比输的多,但往往不够精确,因此如果您对其行为感到惊讶或手册页含糊不清,您应该始终使用标准。在这种情况下,手册页是模糊的,但我不认为它明显是模糊的,我可以看到你是如何阅读它的方式。这是一个原因,为什么我不相信手册页与C标准函数有关。
The strtok() and strtok_r() functions return a pointer to the next token,
or NULL if there are no more tokens.