Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么strtok总是找到模式&引用;?_C_Strtok - Fatal编程技术网

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.