streamstring类介绍

news/2024/11/16 15:54:57/文章来源:https://www.cnblogs.com/hisun9/p/18549407

std::stringstream 是 C++ 标准库中提供的一个类,定义在头文件 <sstream> 中。它是基于字符串的流(stream),允许像操作输入流(std::cin)或输出流(std::cout)那样,操作字符串内容。

std::stringstream 是 std::iostream 的派生类,支持同时进行字符串解析(输入)和字符串构造(输出)。

核心概念

std::stringstream 用字符串作为存储介质,模拟流的行为。

主要用于:

  • 从字符串中提取数据(类似 std::cin)。

  • 将数据写入字符串(类似 std::cout)。

常见成员函数

  • 输入与输出

    <<:将数据写入流中(字符串拼接)。

    >>:从流中提取数据(字符串解析)。

  • 绑定与清空

    • str():获取或设置流内的字符串。

    • clear():清除流状态(但不清除内容)。

举几个例子

1. 字符串构造

将多个数据拼接成字符串:

#include <iostream>
#include <sstream>
#include <string>int main() {std::stringstream ss;ss << "Name: " << "Alice" << ", Age: " << 25; // 写入字符串流std::string result = ss.str(); // 获取流中的字符串std::cout << result << std::endl; // 输出: Name: Alice, Age: 25return 0;
}

输出如下:

img

2. 字符串解析

从字符串中提取数据:

#include <iostream>
#include <sstream>
#include <string>int main() {std::string data = "123 456 789"; // 要解析的字符串std::stringstream ss(data);int a, b, c;ss >> a >> b >> c; // 逐个提取整数std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl; // 输出: a: 123, b: 456, c: 789return 0;
}

输出如下:

img

3. 字符串重用

修改或清空流中的字符串:

#include <iostream>
#include <sstream>int main() {std::stringstream ss;// 第一次使用ss << "Hello, World!";std::cout << ss.str() << std::endl; // 输出: Hello, World!// 重用流ss.str("");            // 清空内容ss.clear();            // 清除状态标志ss << "New String!";std::cout << ss.str() << std::endl; // 输出: New String!return 0;
}

img

插句题外话

如果写成这样:

#include <iostream>
#include <sstream>int main() {std::stringstream ss;// 第一次使用ss << "Hello, World!";std::cout << ss.str() << std::endl; // 输出: Hello, World!ss << "New String!";std::cout << ss.str() << std::endl; // 输出: New String!return 0;
}

输出如下:

img

应用场景

1. 替代 itoa 或 sprintf

std::stringstream 可以将整数或浮点数格式化为字符串:

#include <iostream>
#include <sstream>int main() {int num = 42;std::stringstream ss;ss << "Number: " << num;std::string result = ss.str();std::cout << result << std::endl; // 输出: Number: 42return 0;
}

输出如下:

img

可以看看这篇博客 将数值转换为字符串的函数,涉及到了itoasprintf

2. 解析复杂字符串

从复杂字符串中提取数据,比如读取配置或处理输入:

#include <iostream>
#include <sstream>
#include <string>int main() {std::string input = "Name=John;Age=30;Country=USA";std::stringstream ss(input);std::string item;while (std::getline(ss, item, ';')) { // 按分号分割字符串std::cout << item << std::endl;}return 0;
}

输出如下:

img

3. 文件数据处理

用于处理从文件读取的字符串内容:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>int main() {std::ifstream file("data.txt");std::stringstream buffer;buffer << file.rdbuf(); // 将文件内容读取到字符串流std::string content = buffer.str();std::cout << "File Content:\n" << content << std::endl;return 0;
}

输出如下:

img

其中data.txt内容如下:

img

streamstring类遇到空格或者换行会怎么做

在 C++ 的 std::stringstream 中,空格和换行符的处理取决于使用的输入方式(比如 >> 操作符或 getline 函数):

1. 使用 >> 操作符读取

>> 操作符会将空格和换行符视为分隔符,跳过它们。它会自动提取下一个有效的非空白内容。

比如:

#include <iostream>
#include <sstream>
#include <string>int main() {std::string input = "Hello World\n42";std::stringstream ss(input);std::string word;int number;ss >> word; // 读取第一个单词std::cout << "Word: " << word << std::endl; // 输出: Helloss >> word; // 读取第二个单词std::cout << "Word: " << word << std::endl; // 输出: Worldss >> number; // 读取数字std::cout << "Number: " << number << std::endl; // 输出: 42return 0;
}

输出如下:

img

解释:

  • >> 会跳过所有空白字符(包括空格和换行符)。

  • 每次调用 >> 都会从上次解析停止的位置继续提取。

2. 使用 getline 函数读取

  • std::getline 会按行读取内容,直到遇到换行符 \n

  • 换行符会被作为分隔符,不包含在返回的字符串中。

  • 空格会被视为普通字符,不会跳过。

比如:

#include <iostream>
#include <sstream>
#include <string>int main() {std::string input = "Hello World\n42";std::stringstream ss(input);std::string line;while (std::getline(ss, line)) { // 按行读取std::cout << "Line: " << line << std::endl;}return 0;
}

输出如下:

img

解释:

  • getline 会读取整行内容直到遇到换行符,换行符本身被丢弃。

  • 每次调用 getline 会从流的当前位置继续读取下一行。

3. 混合读取方式

可以根据需要,使用 >>getline 结合解析内容:

#include <iostream>
#include <sstream>
#include <string>int main() {std::string input = "Name: John Doe\nAge: 30";std::stringstream ss(input);std::string label, name;int age;// 使用 >> 提取部分数据ss >> label >> name; // 提取 "Name:" 和 "John"std::cout << label << " " << name << std::endl;// 使用 getline 处理整行std::getline(ss, name); // 提取 " Doe"std::cout << "Name (continued):" << name << std::endl;// 提取下一行ss >> label >> age; // 提取 "Age:" 和 "30"std::cout << label << " " << age << std::endl;return 0;
}

输出如下:

img

4. 空格与换行的处理差异总结

img

注意事项

  • 效率问题:std::stringstream 适合轻量级字符串处理,但对于频繁的字符串拼接操作,性能可能不如 std::string 直接操作高。

  • 状态清理:在重用 std::stringstream 时,记得使用 str("") 清空内容,并用 clear() 重置流状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834640.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爬虫

程序示例: import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegexDemo6 {public static void main(String[] args) {/** 有如下文本, 请按照要求爬取数据. * Java 自从 95 年问世以来, 经历了很多版本, 目前企业中用的最多的是 Java8 和 Java11,…

将数值转换为字符串的函数

在 C++ 中,itoa 和 sprintf 是用于将数值转换为字符串的经典函数。然而,它们有一定的局限性或者安全性问题,现代 C++ 更倾向于使用标准库的解决方案,如 std::to_string 和 std::stringstream,来代替这些函数。 1. itoa 的替代 itoa 是一种将整数转换为字符串的函数,但它不…

20222406 2024-2025-1 《网络与系统攻防技术》实验五实验报告

20222406 2024-2025-1 《网络与系统攻防技术》实验五实验报告 1.实验内容对网站进行 DNS 域名查询,包括注册人、IP 地址等信息,还通过相关命令查询 IP 地址注册人及地理位置。尝试获取 QQ 好友 IP 地址并查询其地理位置。使用 nmap 对靶机环境扫描,获取靶机 IP 活跃状态、开…

delphi 新版内存表 FDMemTable

c++builder XE 官方demo最全60多个 http://community.embarcadero.com/blogs?view=entry&id=8761FireDAC.Comp.Client用好FDMemTable代替之前的ClientDataSet,以前ClientDataSet内存表转换太繁琐了步骤。TClientDataSet *cds = new TClientDataSet(this); DataSetProvid…

理想雪 - 翠鸟协会

写在前面3844 字 | 小说 | 热爱 | 思考 | 表达 | 坚定 | 证明 | 坚守《理想雪》系列故事均为架空世界观,所有人名、地名等与现实世界无任何关联。该系列只且仅只为了说明,小说作者在该情境下会诞生的想法和采取的行动,以及背后的世界观、价值观和人生观。因此将具有强烈的个…

专题课:综合案例5

评委打分解答: 1.首先肯定要键盘录入6个评委的分数6个评委的分数,即6个变量,我们肯定用数组更加方便,因为后面求和求最大值之类的,用数组都更简单 遍历数组,我们每键盘打出一个元素就将其放入数组中 . 2.然后定义求和变量,将6个分数求和3.for循环搭配if筛选求最大、最小…

# 20222403 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 本实践目标是掌握metasploit的用法。 指导书参考Rapid7官网的指导教程。 https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/ 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,search一…

_app搭建笔记

逍遥模拟器端口号:21503 (3)adb install +包名的绝对路径 安装apk包 案例:adb install E:\dcs\two\app\mojibase.apk E:\dcs\two\app\baiduyuedu_5520.apk (4)活动路径名: aapt d badging D:\app\baiduyuedu_3760.apk(5)adb uninstall 包名:卸载 com.baidu.yued…

20222323 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 掌握metasploit的用法。 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,search一下就可以use) ②端口扫描:可以直接用nmap,也可以用Aux中的portscan/tcp等。 ③选做:也可以扫系统版本、漏洞等。 (2)Vsft…

InDesign 2025 for Mac(Id2025)最新激活版20.0.0

InDesign 2025具备强大的功能和灵活的扩展性,支持插件扩展,用户可以根据自身需求自定义工具和工作流程。在处理复杂排版和多页面设计时,InDesign 2025注重用户界面的友好性与功能的直观性,即使是新手用户也能快速上手。 InDesign 2025增强了多模态图文编辑能力,使得图像与…

【跟着阿舜学音乐-笔记】1.12和弦功能与进行原理

七和弦 七和弦是三和弦的基础上叠加三音构成的和弦(四个音的和弦)。其中小大七和弦(CmM7)很少运用,因为调内没有小大七和弦,同时听感上也不是很好。 注:有另一种和弦命名方式,即三和弦与根音呈大小七度的音组成和弦的命名法,该命名法对比上述命名法有个特例——增大七…

看过这个,你可能更了解指针一点(2)

先来看下图你认为以下的打印的结果是什么? 接下来,我们先来分析 ****在1中arr单独放在sizeof内表示整个数组, 因此计算的为整个数组大小。即6乘1得到6 1的答案为6 ****在2中arr没有被单独放在sizeof中, arr此时表示数组首元素的地址,+0则表示计算的是第一个元素地址的大小,…