当前位置: 首页 > 知识库问答 >
问题:

为什么我的两个元组包含相同创建方式的字符串,而不是相等的?

傅博容
2023-03-14

我正在使用Microsoft Visual C将以下程序编译为C 20程序:

#include <iostream>
#include <tuple>

int main()
{
    auto t1 = std::make_tuple("one", "two", "three");
    auto t2 = std::make_tuple("one", "two", "three");
    
    std::cout << "(t1 == t2) is " << std::boolalpha << (t1 == t2) << "\n";
    std::cout << "(t1 != t2) is " << std::boolalpha << (t1 != t2) << "\n";

    return 0;
}

当我运行它时,我看到以下输出:

(t1 == t2) is false
(t1 != t2) is true

元组是相同的,那么为什么它有错误的比较结果呢?我该如何解决这个问题?

共有3个答案

子车高歌
2023-03-14

这个问题与C20无关,但源于字符串字面值的实现方式。例如,答案如下:

为什么(仅)某些编译器对相同的字符串文本使用相同的地址?

简而言之,您的程序属于“ 定义 未指定行为”类别,因为它假定相同的C样式字符串文字具有相同的地址。这是因为像“a”==“a”这样的表达式比较地址,而不是内容。如果您使用std::string文本,例如“one”s

江展
2023-03-14

“一”的类型是什么?这不是字符串,而是字符串文本。

您的问题基本上归结为以下代码

char const* a = "one";
char const* b = "one";

std::cout << "(a == b) is " << std::boolalpha << (a == b) << "\n";
std::cout << "(a != b) is " << std::boolalpha << (a != b) << "\n";

这很可能会输出相同的结果。

这是因为字符串文字将衰减为char const*。比较两个指针会比较它们在内存中的位置。现在,问题是编译器是否将字符串文字折叠为一个。如果字符串文字折叠,那么它们将相等,如果不折叠,它们将不相等。这可能因不同的优化级别而异。

那么,您如何确定您的比较呢?

最好使用std::string_view,因为您似乎不需要拥有或更改其内容:

using namespace std::literals;

// ... 

auto t1 = std::make_tuple("one"sv, "two"sv, "three"sv);
auto t2 = std::make_tuple("one"sv, "two"sv, "three"sv);

std::string_view 类是围绕指针和大小的薄包装器,并定义一个检查值是否相等的比较运算符。

傅胡媚
2023-03-14

您正在将指针与字符缓冲区(而不是字符串)进行比较。

有时编译器会将两个不同的“one”转换为同一个缓冲区,有时则不会。

在你的情况下,它不是。可能是调试版本。

添加#include

using namespace std::literals;

auto t1 = std::make_tuple("one"sv, "two"sv, "three"sv);
auto t2 = std::make_tuple("one"sv, "two"sv, "three"sv);

你会得到你所期望的。(在 c 之前的 17 编译器中,使用

 类似资料:
  • "给定两个字符串s和t,编写一个函数来检查s是否包含t的所有字符(顺序与字符串t相同)。返回true或false。递归不一定。这是我用java写的代码片段。问题是输入: string1="st3h5irteuyarh!"和string2="shrey"它应该返回TRUE,但它返回FALSE。那是为什么?"

  • 问题内容: 通过搜索发现了类似的问题,但我是一位新的(糟糕的)程序员,无法理解答案。 我有一个.txt文件,其中包含多个字符串,以’-‘分隔。我使用拆分将一些字符串分成变量,其中两个相等,但是在if语句中它们不相等。 这将产生以下结果: 瑞典 瑞典 没有 在两个“ Sweden”字符串之前和之后都有一个空格,并且它们都用大写字母“ S”编写,但不相等吗?我在哪里搞砸了? 问题答案: 最后一个元素包

  • 问题内容: 似乎以下代码应返回true,但返回false。 这有什么意义? 问题答案: 常规()和严格()相等之间的唯一区别是,严格相等运算符禁用类型转换。由于已经在比较两个相同类型的变量,因此使用的相等运算符的类型无关紧要。 不管您使用常规相等还是严格相等,对象比较仅 在您比较相同的精确对象时得出 。 也就是说,给定,,,但。 两个不同的对象(即使它们都具有零或相同的精确属性)也永远不会相等地进

  • 问题内容: 拥有Java代码 该字符串将分配在相同的内存位置(或多倍): 是否多次启动同一程序(并行)执行? 可能的答案: 我目前是C#开发人员(尽管在上个千年中使用Java编程)。 我之所以问这个问题,是因为我相信.NET CLR和Java(JVM)之间是相同的,我希望得到.NET应用程序的答案(但由于经常遇到的“应用程序”池术语而引起疑问)。 答案是 字符串 实习生池由同一JVM或.NET C

  • 问题内容: 我有两个字符串,它们看起来都一样: 但是,检查相等性表明它们不是。 我还尝试从命令提示符中复制两个字符串,并将它们作为新变量粘贴回去,但是它们仍然不相等。我有80%的把握是因为它们的编码方式很怪异,插入了一些我看不见的奇数字符,但是使用type()都只是显示为字符串。 有什么办法可以看到“真实”字符串?任何帮助表示赞赏。 问题答案: 他们是不一样的; using显示了这两个值之间的差异

  • 问题内容: 这个问题已经在这里有了答案 : 2个相同的字符串“不相等” [Python] (1个答案) Python两个相同的字符串被视为不同 (1个答案) 去年关闭。 我正在尝试使用python编写聊天服务器。我正在使用SHA1哈希来验证用户,并将用户存储的哈希与给定密码的哈希进行比较,如果它们相同,则应该验证用户。 我的哈希函数如下所示: 我的验证用户如下所示: 当我与一个我知道在列表中的用户