比较字符串元素与字符串的区别

12
以下代码会输出什么:
1
0

我一直在想,如果比较的是同一个字符串,为什么值不同... 我已经苦恼了一段时间,无法弄清楚为什么它们返回不同的布尔值。

int main()
{
    string stringArray[] = { "banana","Banana","zebra","apple","Apple","Zebra","cayote" };

    cout << (stringArray[1] < stringArray[0]) << endl;
    cout << ("Banana" < "banana") << endl;

    return 0;
}

使用 strcmp 比较字符串。 - Thane Plummer
2
在第二种情况下,您没有比较两个字符串对象。以下内容与第一种情况相同: cout << (std :: string(“Banana”)<std :: string(“banana”))<< endl; - DeiDei
8
@ThanePlummer 不,这是C++。 - emlai
2
@ThanePlummer:strncmp 无法与 std::string 一起使用,除非您执行以下操作:strncmp(stringArray[1].c_str(), stringArray[0].c_str()) - Thomas Matthews
@zenith 不管是C还是C++,strcmp在两种语言中都是有效的。@Thomas指出对于std::string对象需要进行转换是正确的。 - Thane Plummer
1
在C++中,通常应该使用std::string及其比较运算符重载和compare成员函数。而while true则表示循环体会一直执行下去。 - emlai
3个回答

17

stringArray[n]是一个std::string,但"Banana"是一个字符串字面值(由char数组组成)。

当你执行"Banana" < "banana"时,两个字符串字面值都会被隐式转换为指向char数组的char指针。<然后比较这些内存地址。


8

"Banana" < "banana"并不是在比较字符串的内容,而是比较指向"Banana""banana"的指针。

如果要比较C风格字符串而不将它们转换为std::string,您可以使用strcmp()


1
你也可以使用 std::string("Banana") < std::string("banana") - Fantastic Mr Fox
2
@Ben:创建一个临时 std::string 就足够了。尽管出于可读性考虑我也会像这样做。 - Christian Hackl
1
@NathanOliver:在某种程度上,“很多”...:)它肯定比使用strcmp更少出错,并且不会混淆三个不同的结果。(我必须承认,我需要阅读函数的文档,以了解-1是表示第一个还是第二个更大,或者它可以是任何负数等。) - Christian Hackl

7
string stringArray[] = { "banana","Banana","zebra","apple","Apple","Zebra","cayote" };

这意味着您会得到一堆std :: string对象,这些对象是从单个字符串字面量生成的char const *

考虑一个单独的std :: string初始化:

std::string s = "...";

右侧的文字是char const[4]类型。它会被“衰减”成char const*,用于std::string构造函数。

当您使用字符串字面值初始化std::string对象数组时,同样会发生这种情况。

cout << (stringArray[1] < stringArray[0]) << endl;
对于`std::string`类型,使用操作符`<`表示按字典序大小比较。因此,这个操作会按字典序大小比较两个字符串,并得到期望的结果。
cout << ("Banana" < "banana") << endl;
在这种情况下,没有涉及到 std::string。你要比较两个 char const[7]
这意味着什么?结果完全不同。两个数组都会“退化”为一个指向它们第一个元素的 char const* 指针。使用 < 比较两个不相关的指针的结果是未指定的。你很幸运得到了0作为结果,因为你也可能得到1而没有注意到错误。编译器也可以为此生成警告,例如:
warning: comparison with string literal results in unspecified behaviour

可以看出,这个操作与词汇顺序比较完全没有关系。

解决这个问题的一种方法是将至少一个操作数转换为 std::string 类型:

cout << (string("Banana") < "banana") << endl;

比较一个 std::string 和一个 char const*(或反之)被定义为按字典顺序排序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接