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

2023-11-30 12:38

本文主要是介绍为什么 std::ends 会导致字符串比较失败?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题

我昨天花了大约 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、 makehi和不同的长度。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 会导致字符串比较失败?

这篇关于为什么 std::ends 会导致字符串比较失败?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437066

相关文章

Springboot3+将ID转为JSON字符串的详细配置方案

《Springboot3+将ID转为JSON字符串的详细配置方案》:本文主要介绍纯后端实现Long/BigIntegerID转为JSON字符串的详细配置方案,s基于SpringBoot3+和Spr... 目录1. 添加依赖2. 全局 Jackson 配置3. 精准控制(可选)4. OpenAPI (Spri

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

使用Python实现base64字符串与图片互转的详细步骤

《使用Python实现base64字符串与图片互转的详细步骤》要将一个Base64编码的字符串转换为图片文件并保存下来,可以使用Python的base64模块来实现,这一过程包括解码Base64字符串... 目录1. 图片编码为 Base64 字符串2. Base64 字符串解码为图片文件3. 示例使用注意

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

Python如何判断字符串中是否包含特殊字符并替换

《Python如何判断字符串中是否包含特殊字符并替换》这篇文章主要为大家详细介绍了如何使用Python实现判断字符串中是否包含特殊字符并使用空字符串替换掉,文中的示例代码讲解详细,感兴趣的小伙伴可以了... 目录python判断字符串中是否包含特殊字符方法一:使用正则表达式方法二:手动检查特定字符Pytho

MySQL 字符串截取函数及用法详解

《MySQL字符串截取函数及用法详解》在MySQL中,字符串截取是常见的操作,主要用于从字符串中提取特定部分,MySQL提供了多种函数来实现这一功能,包括LEFT()、RIGHT()、SUBST... 目录mysql 字符串截取函数详解RIGHT(str, length):从右侧截取指定长度的字符SUBST

Python将字符串转换为小写字母的几种常用方法

《Python将字符串转换为小写字母的几种常用方法》:本文主要介绍Python中将字符串大写字母转小写的四种方法:lower()方法简洁高效,手动ASCII转换灵活可控,str.translate... 目录一、使用内置方法 lower()(最简单)二、手动遍历 + ASCII 码转换三、使用 str.tr

Java如何用乘号来重复字符串的功能

《Java如何用乘号来重复字符串的功能》:本文主要介绍Java使用乘号来重复字符串的功能,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java乘号来重复字符串的功能1、利用循环2、使用StringBuilder3、采用 Java 11 引入的String.rep

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Java实现按字节长度截取字符串

《Java实现按字节长度截取字符串》在Java中,由于字符串可能包含多字节字符,直接按字节长度截取可能会导致乱码或截取不准确的问题,下面我们就来看看几种按字节长度截取字符串的方法吧... 目录方法一:使用String的getBytes方法方法二:指定字符编码处理方法三:更精确的字符编码处理使用示例注意事项方