2015-06-17 81 views
1

我刚碰到一个非常奇怪的问题。我具备的功能很简单:C++ string.length()奇怪的行为

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,你可以自己尝试一下......

+0

@aslg没有,你可以试试大小()也一样,相同的行为。 – Arch1tect

+0

@aslg根据[文档](http://en.cppreference.com/w/cpp/string/basic_string/size),它们没有区别。 – Sinkingpoint

+0

长度和大小与我的知识相同。 'I = 0;我<= -1;我++需要一段时间才能到达退出案例。 – user4581301

回答

3

这是因为.length()(和.size())回报size_t,这是一个无符号整数。你认为你得到一个负数,实际上它下溢回size_t(在我的机器上,这是18446744073709551615)的最大值。这意味着您的for循环将循环遍历size_t的所有可能值,而不是像您期望的那样立即退出。

为了得到你想要的结果,你可以明确的大小转换为int S,而不是unsigned int s(参照aslgs回答),尽管这可能会失败有足够长度的字符串(足以过/欠流标准int

编辑: 从下面的评论有两种解决方案:

  1. (尼尔·弗里德曼)而不是使用int在aslg的回答,包括头和使用int64_t,这将避免上述问题。

  2. (rici)将您的for循环转换为for(int i = 0;needle.length() + i <= haystack.length();i ++){,通过重新排列等式来避免所有这些问题在一起,以避免所有的减法。

+0

由于您记下的原因,int并不是一个很好的建议。在大多数体系结构中,int只有32位。相反,我建议#including 并使用int64_t或long long int(保证至少64位)。这将适用于所有字符串,除非您的计算机具有2^63字节的RAM。 –

+0

或者通过写入条件来避免这个问题:'needle.length()+ i <= haystack.length()' – rici

+0

@NirFriedman我在我的答案中包含了这个建议 – Sinkingpoint

1
(haystack.length()-needle.length()) 

length返回size_t,换言之一个unsigned int。给定字符串的大小,分别为0和1,当计算差值时,下溢并成为无符号整数的最大可能值。 (这是用于存储的4个字节的约4.2亿,但也可以是不同的值)

i<=(haystack.length()-needle.length()) 

分度器i是由编译器变换为一个无符号的int类型匹配的。所以你必须等到i大于unsigned int的最大可能值。它不会停止。

解决方案:

你必须将每个方法的结果为int,像这样,

i <= ((int)haystack.length() - (int)needle.length()) 
+0

@Quirliom Fixed。 – aslg