C++ string.length() 奇怪的行为
Posted
技术标签:
【中文标题】C++ string.length() 奇怪的行为【英文标题】:C++ string.length() Strange Behavior 【发布时间】:2015-06-17 00:28:45 【问题描述】:我刚刚遇到了一个非常奇怪的问题。我的功能很简单:
int strStr(string haystack, string needle)
for(int i=0; i<=(haystack.length()-needle.length()); i++)
cout<<"i "<<i<<endl;
return 0;
那如果我调用strStr("", "a")
,虽然haystack.length()-needle.length()=-1
,这不会返回0,你可以自己试试……
【问题讨论】:
@aslg 不,你也可以试试 size(),同样的行为。 @aslg 根据docs,它们并没有什么不同。 据我所知,长度和大小是相同的。i=0; i <= -1; i++
需要一段时间才能到达出口案例。
@user4581301 为什么要花一点时间?根本不应该进入循环
因为 -1 是一个无符号整数。
【参考方案1】:
这是因为.length()
(和.size()
)返回size_t
,这是一个无符号整数。你认为你得到一个负数,而实际上它下溢回到size_t
的最大值(在我的机器上,这是 18446744073709551615)。这意味着您的 for 循环将遍历 size_t 的所有可能值,而不是像您期望的那样立即退出。
要获得您想要的结果,您可以将大小显式转换为 int
s,而不是 unsigned int
s(请参阅 aslgs 答案),尽管对于具有足够长度的字符串(足以溢出/不足),这可能会失败一个标准的int
)
编辑: 来自以下 cmets 的两个解决方案:
(Nir Friedman) 不要像 aslg 的回答那样使用 int
,而是包含标题并使用 int64_t,这将避免上述问题。
(rici) 将您的 for 循环转换为 for(int i = 0;needle.length() + i <= haystack.length();i ++)
,通过重新排列等式来避免所有减法,从而避免所有问题。
【讨论】:
由于您提到的原因, int 不是一个很好的建议。在大多数体系结构中,int 只有 32 位。相反,我建议 #includeneedle.length() + i <= haystack.length()
来避免问题【参考方案2】:
(haystack.length()-needle.length())
length
返回一个size_t
,换句话说,一个无符号整数。给定字符串的大小,分别为 0 和 1,当您计算差异时,它会下溢并成为 unsigned int 的最大可能值。 (对于 4 个字节的存储,这大约是 42 亿,但可能是不同的值)
i<=(haystack.length()-needle.length())
编译器将索引器i
转换为无符号整数以匹配类型。所以你必须等到i
大于无符号整数的最大可能值。它不会停止。
解决方案:
你必须将每个方法的结果转换为int,像这样,
i <= ( (int)haystack.length() - (int)needle.length() )
【讨论】:
以上是关于C++ string.length() 奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章