ITPub博客

首页 > 应用开发 > C/C++ > 为什么 std::ends 会导致字符串比较失败?

为什么 std::ends 会导致字符串比较失败?

C/C++ 作者:itchaindev 时间:2022-04-11 21:27:28 0 删除 编辑

 问题

我昨天花了大约 4 个小时试图在我的代码中解决这个问题。我将问题简化为下面的示例。

这个想法是将字符串存储在以 stringstream结尾 std::ends,然后稍后检索它并将其与原始字符串进行比较。

#include <sstream>
#include <iostream>
#include <string>
int main( int argc, char** argv )
{
    const std::string HELLO( "hello" );
    std::stringstream testStream;
    testStream << HELLO << std::ends;
    std::string hi = testStream.str();
    if( HELLO == hi )
    {
        std::cout << HELLO << "==" << hi << std::endl;
    }
    return 0;
}

正如您可能猜到的那样,上面的代码在执行时不会打印任何内容。

虽然,如果打印出来,或者在调试器(VS2005)中查看, HELLO并且 hi看起来相同,它们 .length()实际上相差 1。这就是我猜测导致 ==操作员失败的原因。

我的问题是为什么。我不明白为什么即使它们具有相同的内容,也会 std::ends将一个不可见的字符添加到 string  hi、 make hi和不同的长度。 HELLO此外,这个不可见的角色不会被增强修剪修剪。但是,如果您用于 strcmp比较 .c_str()两个字符串,则比较可以正常工作。

我首先使用的原因 std::ends是因为我过去 stringstream在流的末尾保留垃圾数据时遇到过问题。 std::ends为我解决了这个问题。

解决方案

std::ends只是一个空字符。传统上,C 和 C++ 中的字符串以空(ascii 0)字符结尾,但事实证明这 std::string并不真正需要这个东西。无论如何,要逐点执行您的代码,我们会看到一些有趣的事情发生:

int main( int argc, char** argv )
{

字符串文字 "hello"是传统的以零结尾的字符串常量。我们将整个复制到 std::stringHELLO 中。

   const std::string HELLO( "hello" );
    std::stringstream testStream;

我们现在将 stringHELLO(包括尾随的 0)放入 stream,然后是第二个 null ,它通过调用 放在那里 std::ends。

std::ends。
    testStream << HELLO << std::ends;

我们提取出我们放入的内容的副本 stream(文字字符串“hello”,加上两个空终止符)。

    std::string hi = testStream.str();

operator ==然后我们使用类上的比较这两个字符串 std::string。该运算符(可能)比较 string对象的长度 – 包括有多少尾随空字符。请注意, std::string该类不要求底层字符数组以尾随空字符结尾——换句话说,它允许字符串包含空字符,因此两个尾随空字符中的第一个被视为字符串的一部分 hi。

由于两个字符串的尾随空值数量不同,因此比较失败。

    if( HELLO == hi )
    {
        std::cout << HELLO << "==" << hi << std::endl;
    }
    return 0;
}

虽然,如果打印出来,或者在调试器(VS2005)中查看,HELLO 和 hi 看起来相同,但它们的 .length() 实际上相差 1。这就是我猜测导致“==”运算符失败的原因。

原因是,长度相差一个尾随空字符。

我的问题是为什么。我不明白为什么 std::ends 是添加到字符串 hi 的不可见字符,即使 hi 和 HELLO 具有相同的内容,它们的长度也会不同。此外,这个不可见的角色不会被增强修剪修剪。但是,如果您使用 strcmp 比较两个字符串的 .c_str(),则比较可以正常进行。

strcmp不同于 std::string– 它是在早期以空值终止字符串时写的 – 所以当它到达第一个尾随空值时 hi它停止查找。

我首先使用 std::ends 的原因是因为我过去遇到过 stringstream 在流末尾保留垃圾数据的问题。std::ends 为我解决了这个问题。

有时,了解底层表示是一个好主意。

原文链接: 为什么 std::ends 会导致字符串比较失败?


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70016198/viewspace-2886591/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2022-04-02

  • 博文量
    12
  • 访问量
    3420