【问题标题】:C++ Comparing Strings Using Relational OperatorC++ 使用关系运算符比较字符串
【发布时间】:2018-08-15 16:09:00
【问题描述】:

有人可以澄清这个比较过程中实际发生的事情吗?

如果我有,在 C++ 程序中:

string name1 = "Mary";

我愿意:

name1 < "Mary Jane" // true

为什么这是真的?如果 C++ 将每个字符与每个字符进行比较,并且第一个不匹配的字符是 name1 = "Mary" 末尾的单双引号与 "Mary Jane" 中的空格值,那么通过 ASCII 值,空格值小于单个引号...

【问题讨论】:

  • 开始here 并沿着兔子洞往下走……
  • 引号不是比较的一部分。
  • "name1 末尾的单引号" - 我没有看到单引号。
  • @drescherjm - 因为它们不是字符串的一部分。
  • 是的,不,这不是字符串的一部分。这是引入您初始化字符串的字符串文字的语法,但 " 不是字符串本身的一部分

标签: c++ string operators relational


【解决方案1】:
string name1 = "Mary";

让我们解开这个,有几件事正在发生。

令牌

"Mary"

单独来看是一个string literal,它粗略地计算为数组

const char literal_array[5] = { 'M', 'a', 'r', 'y', 0 };

您可以看到为什么值得拥有一些语法糖 - 为每个字符串都写出来会很糟糕。

无论如何,其中没有 " 字符 - 它们用于告诉编译器发出该字符串文字,但它们不是字符串本身的一部分。

然后,一旦我们知道表达式的右侧是什么,我们就可以查看左侧:

string name1 = "Mary"

真的

string name1(literal_array);

使用构造函数

basic_string<char>::basic_string<char>(const char *)

我稍微解释一下,但它是第 5 项 here


name1 < "Mary Jane"

现在我们终于知道左边是什么了,我们可以看看这个表达式,它展开为

const char literal_array2[10] = { 'M', 'a', 'r', 'y', ' ', 'J', 'a', 'n', 'e', 0 };
operator< (name1, literal_array2)

这是第 9 个重载 here(在撰写本文时),并将 compare 称为

name1.compare(literal_array2)

这被描述为执行以下操作:

4) 将此字符串与从 s 指向的字符开始的空终止字符序列进行比较,就像 compare(basic_string(s)) 一样

这将我们带回到第一个重载:

1) 首先,计算要比较的字符数,好像按

size_type rlen = std::min(size(), str.size()).

然后通过调用比较

Traits::compare(data(), str.data(), rlen).

对于标准字符串,此函数执行逐个字符的字典比较。

如果结果为零(到目前为止字符串相等),

请注意,到目前为止,我们刚刚将“Mary”与“Mary”进行了比较

然后它们的大小比较如下:

size(data) < size(arg)    => data is less than arg    => result <0

其中“结果operator< 将返回true。

【讨论】:

  • 我如何学习阅读您​​提供的 C++ 参考信息。我目前正在从 Control Structures 到 Objects 8th Edition 阅读 C++,但我不知道如何理解您提供的源代码。
  • 您不了解哪些具体位?我没有那本书,不知道你在哪里或它涵盖了什么,遗憾的是无法读懂你的想法。如果您引用一些您无法理解的内容,我至少可以尝试。
  • 我无法阅读您在本网站提供的信息:en.cppreference.com/w/cpp/string/basic_string/basic_string我如何学会阅读这些行?
  • 这有点吵,因为basic_string 是一个模板:例如。对于大多数用途,您可以将basic_string(const CharT*...) 简化为string(const char* ...)。页面顶部只是构造函数重载的列表,如果您的书涉及对象,应该熟悉它。您可以稍后再忽略分配器参数,因为默认值很好。
  • “我不知道如何理解......”。一些线索通常在 cppreference 页面底部的示例中提供。
【解决方案2】:

重载的&lt; 运算符不比较字符串中的""" 用于表示字符串,以便编译器将其解析为字符串。它们不是字符串的一部分。

【讨论】:

    【解决方案3】:

    虽然我们在 C++ 中编写了用引号括起来的字符串文字,但这些引号实际上并不是字符串的一部分。这意味着您在此处实际比较的字符串是 MaryMary Jane,不带引号。

    C++ 按字典顺序比较字符串,这意味着它一次只去一个字符,直到发现不匹配或其中一个字符串结束。如果在其中一个字符串结束之前没有发现不匹配,则较短的字符串比较小,因此您在此处看到的结果。

    【讨论】:

    • 是的,因为较短的字符可以用空字符填充,所有这些都将小于较长的字符值。
    • 对于 C++ 字符串,这实际上不一定正确。 C++ std::string 对象可以包含空字符,因此填充参数可能会错误地导致您得出两个不同字符串比较相等的结论。例如,由 5 个空字符组成的 std::string 将比由 137 个空字符组成的 std::string 少,但如果用空字符填充它们,它们将是相同的字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2022-12-01
    • 2017-09-27
    • 2013-08-23
    • 2016-10-22
    • 1970-01-01
    • 2012-10-05
    相关资源
    最近更新 更多