【问题标题】:Unexpected results when comparing strings比较字符串时出现意外结果
【发布时间】:2016-09-17 09:38:10
【问题描述】:

我正在比较这两个字符串:"code""test"

当我在 Visual Studio 中键入时:

cout<<("t"<"c")<<endl;
cout<<("c"<"t")<<endl;
cout<<("code"<"test")<<endl;
cout<<("test"<"cose")<<endl;

结果是:

1
0
1
1

这没有意义,当我尝试在ideone.com上尝试时,结果变为:

0
1
1
1

这里出了什么问题?

【问题讨论】:

    标签: c++ string compare


    【解决方案1】:

    您正在比较指针值,而不是字符串(注意:"cose""code" 是不同的文字,¹保证给出不同的指针)。

    使用来自&lt;string&gt; 标头的std::string 来获得有意义的字符串操作。

    那么你也可以使用像"code"s这样的字面量。

    #include <iostream>
    #include <string>
    using namespace std;
    
    auto main() -> int
    {
        cout << boolalpha;
        cout << ("t"s < "c"s) << endl;
        cout << ("c"s < "t"s) << endl;
        cout << ("code"s < "test"s) << endl;
        cout << ("test"s < "cose"s) << endl;
    }
    

    正式的问题中的代码,

    cout<<("t"<"c")<<endl;
    cout<<("c"<"t")<<endl;
    cout<<("code"<"test")<<endl;
    cout<<("test"<"cose")<<endl;
    

    …具有实现定义的行为,因为

    C++11 §5.9/2 2nd 破折号(expr.rel):

    如果两个相同类型的指针pq 指向不同的对象,这些对象不是同一对象的成员或同一数组的元素或不同的函数,或者如果其中只有一个为空,p&lt;qp&gt;qp&lt;=qp&gt;=q 的结果未指定。

    但是,您可以通过std::less 和家人以明确定义的方式比较这些指针,因为

    C++11 20.8.5/8(比较):

    对于模板greaterlessgreater_equalless_equal,任何指针类型的特化都会产生一个总顺序,即使内置运算符@987654339 @、&gt;&lt;=&gt;= 不要。

    但是在第三只手上,虽然指针比较在某些情况下很有用,但您可能想要比较字符串文字。标准库提供例如strcmp 为了做到这一点。但最好使用std::string,如开头所述。


    文字"code" 表示char 值的不可变空终止字符串。最后一个空字节共有五个char 值。因此类型是char const[5]

    作为在需要指针的上下文中使用的表达式,表示此数组的表达式(即"code" 文字)衰减为指向第一项的指针,char const* 指针。

    这是数组表达式到指针的通常衰减,但在 C++03 和更早的版本中,还有一个用于文字的特殊规则,允许衰减到 char*(没有 const)。


    注意事项:
    ¹ 两个相同的字符串文字可以给出不同的指针或相同的指针,具体取决于所使用的编译器和选项。

    【讨论】:

      【解决方案2】:

      字符串字面量,例如"t" 实际上是常量字符数组(包括终止符)。

      当你使用字符串字面量时,你得到的是一个指向它的第一个字符的指针。

      因此,当您执行"t" &lt; "c" 时,您正在比较两个不相关的指针。 "t" &lt; "c" 是否为真取决于编译器决定将字符串文字数组放在哪里。

      如果你想比较字符串,你应该使用std::string,或者旧的C函数strcmp

      【讨论】:

      • “当你使用字符串文字时,你得到的是指向它的第一个字符的指针。”。这通常是正确的,但一般情况下并非如此。
      猜你喜欢
      • 1970-01-01
      • 2014-01-21
      • 2012-08-25
      • 2022-01-25
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 1970-01-01
      • 2019-12-21
      相关资源
      最近更新 更多