为什么 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

相关文章

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

Java使用正则提取字符串中的内容的详细步骤

《Java使用正则提取字符串中的内容的详细步骤》:本文主要介绍Java中使用正则表达式提取字符串内容的方法,通过Pattern和Matcher类实现,涵盖编译正则、查找匹配、分组捕获、数字与邮箱提... 目录1. 基础流程2. 关键方法说明3. 常见场景示例场景1:提取所有数字场景2:提取邮箱地址4. 高级

Python如何实现高效的文件/目录比较

《Python如何实现高效的文件/目录比较》在系统维护、数据同步或版本控制场景中,我们经常需要比较两个目录的差异,本文将分享一下如何用Python实现高效的文件/目录比较,并灵活处理排除规则,希望对大... 目录案例一:基础目录比较与排除实现案例二:高性能大文件比较案例三:跨平台路径处理案例四:可视化差异报

Python 字符串裁切与提取全面且实用的解决方案

《Python字符串裁切与提取全面且实用的解决方案》本文梳理了Python字符串处理方法,涵盖基础切片、split/partition分割、正则匹配及结构化数据解析(如BeautifulSoup、j... 目录python 字符串裁切与提取的完整指南 基础切片方法1. 使用切片操作符[start:end]2

MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)

《MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)》本文给大家介绍MyBatis的xml中字符串类型判空与非字符串类型判空处理方式,本文给大家介绍的非常详细,对大家的学习或... 目录完整 Hutool 写法版本对比优化为什么status变成Long?为什么 price 没事?怎

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1