为什么 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字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义