【C++】stringstream

stringstream 定义于头文件 <sstream>,它其实是个别名,具体定义如下:

typedef basic_stringstream<char> stringstream;
<sstream> 定义了三个类:istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作。本文以 stringstream 为主,介绍流的输入和输出操作。<sstream> 主要用来进行数据类型转换,由于 <sstream> 使用 string 对象来代替字符数组(snprintf 方式),避免了缓冲区溢出的危险;而且,因为传入参数和目标对象的类型会被自动推导出来,所以不存在错误的格式化符号的问题。简单说,相比 C 编程语言库的数据类型转换,<sstream> 更加安全、自动和直接.

类模板 std::basic_stringstream 实现基于字符串的流上的输入与输出操作。它等效地存储一个 std::basic_string 的实例,并在其上进行输入与输出操作。继承图如下:

继承图

构造函数

创建一个对象,向对象输入字符串:

stringstream ss;
ss << str;

在创建对象的时候使用字符串初始化:

streamstring ss(str);

两种方式都可以创建对象,但创建后的对象用法不一样.

输出字符串

stringstream 可以将存储于内部的字符串输出,需要调用 str() 函数,不可直接输出:

std::cout << ss.str() << std::endl;
// std::cout << ss << std::endl; 		// 错误不可直接输出

上面阐述了两种构造函数,利用不同的构造函数创建对象,对象具体的操作也不同:

第一种构造方式

#include <iostream>
#include <sstream>
using namespace std;
int main()
{stringstream ss1;ss1 << "fre";ss1 << "gre";cout << ss1.str() << endl;return 0;
}
/*
输出:
fregre
*/

第二种构造方式

#include <iostream>
#include <sstream>
using namespace std;
int main()
{string str("asd");stringstream ss2(str);cout << ss2.str() << endl;ss2 << "r";cout << ss2.str() << endl;ss2 << "13";cout << ss2.str() << endl;ss2 << "hy";cout << ss2.str() << endl;return 0;
}
/*
输出:
asd
rsd
r13
r13hy
*/

可以发现,利用第一种构造函数创建对象时,输入字符串后直接进行字符串拼接,而第二种构造方式,在进行字符串拼接时,首先把原本的字符串覆盖掉,之后再进行拼接。

如果不想原来的字符串被覆盖,则需要换一种构造方式,如下:

#include <iostream>
#include <sstream>
using namespace std;
int main()
{ostringstream ss("1 2 3 4 ", std::ios_base::ate);	// append 方式追加cout << ss.str() << endl;ss << "5 3 4";cout << ss.str() << endl;return 0;
}
/*
输出:
1 2 3 4 
1 2 3 4 5 3 4
*/

连接多个字符串

#include <iostream>
#include <sstream>
#include <string>int main() {std::stringstream ss;ss << "one" << " two" << " three" << " four";std::string str = ss.str();std::cout << str << std::endl; // 输出 "one two three four"return 0;
}

格式化输出

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>int main() {double pi = 3.14159265358979323846;std::stringstream ss;ss << std::fixed << std::setprecision(2) << pi;std::string str = ss.str();std::cout << str << std::endl; // 输出 "3.14"return 0;
}

检查 stringstream 对象是否为空

可以使用 str().empty() 函数来检查 stringstream 对象是否为空。

#include <iostream>
#include <sstream>
#include <string>int main() {int num = 12345;std::stringstream ss;if (ss.str().empty()) {std::cout << "Empty" << std::endl; // 输出 "Empty"}ss << num;if (!ss.str().empty()) {std::cout << "Not empty" << std::endl; // 输出 "Not empty"}return 0;
}

使用 getline 函数读取一整行

#include <iostream>
#include <sstream>
#include <string>int main() {std::string str = "one\ntwo\nthree\nfour";std::stringstream ss(str);std::string line;while (std::getline(ss, line)) {std::cout << line << std::endl;}return 0;
}

使用 peek 函数查看下一个字符

我们可以使用 peek 函数查看 stringstream 对象中的下一个字符,而不会改变 stringstream 对象的状态。下面是一个例子:

#include <iostream>
#include <sstream>
#include <string>int main() {std::string str = "12345";std::stringstream ss(str);char ch = ss.peek();std::cout << ch << std::endl; // 输出 '1'int num;ss >> num;std::cout << num << std::endl; // 输出 12345return 0;
}

使用 putback 函数将字符放回 stringstream 对象

#include <iostream>
#include <sstream>
#include <string>int main() {std::string str = "12345";std::stringstream ss(str);char ch;ss.get(ch);// 将字符 '1' 放回 stringstream 对象中ss.putback(ch);int num;ss >> num;// 输出 12345// 如果没有使用 putback 函数,则输出 2345std::cout << num << std::endl; return 0;
}

修改、清空 stringstream 内容

stringstream 的内容可以通过 str() 函数进行修改、清空:

#include <iostream>
#include <sstream>
using namespace std;
int main()
{stringstream ss("fghewoo");cout << ss.str() << endl;// 修改内容ss.str("123456");cout << ss.str() << endl;// 清空内容ss.str("");cout << ss.str() << endl;return 0;
}
/*
输出:
fghewoo
123456*///ss.clear(); // 清空状态位(例如错误标志)

利用 stringstream 去除字符串空格

stringstream 默认是以空格来分割字符串的,利用 stringstream 去除字符串空格非常方便:

#include <iostream>
#include <sstream>
using namespace std;
int main()
{stringstream ss("2 dfjho 43");cout << ss.str() << endl;cout<< endl;string str;while (ss >> str){cout << str << endl;}return 0;
}
/*
输出:
2 dfjho 432 
dfjho 
43
*/

利用 stringstream 指定字符分割字符串

上面描述了利用 stringstream 去除字符串空格,其实就是利用空格来分割字符串,同样,也可以指定其他字符对字符串进行分割,这需要与 getline() 函数搭配使用,下面以逗号分割字符串为例:

#include <iostream>
#include <sstream>
using namespace std;
int main()
{string source = "abc,123,<!>";stringstream ss(source);cout << ss.str() << endl;cout<< endl;string str;while (getline(ss, str, ',')){cout << str << endl;}return 0;
}
/*
输出:
abc,123,<!>abc
123
<!>
*/

上述代码以逗号作为分割依据来分割字符串,同样的还可以扩展到其他字符。

逐个提取数据

你可以使用 stringstream 来逐个提取以特定格式存储在字符串中的数据,例如:

#include <sstream>
#include <iostream>int main() {std::string data = "John 25 Programmer";std::stringstream ss(data);std::string name;int age;std::string occupation;ss >> name >> age >> occupation;std::cout << "Name: " << name << std::endl;std::cout << "Age: " << age << std::endl;std::cout << "Occupation: " << occupation << std::endl;
}

这里,stringstream 会根据空白字符自动分割字符串,并按照顺序将值赋给相应的变量。

运行结果:

Name: John
Age: 25
Occupation: Programmer

向字符串中逐个插入数据

stringstream 还可以往一个字符串中逐项插入数据,通过对流进行格式化,可以方便地构建具有复杂格式的字符串。

#include <sstream>
#include <iostream>int main() {std::stringstream ss;std::string name = "John";int age = 30;double salary = 60000.5;ss << "Name: " << name << ", Age: " << age << ", Salary: " << salary;std::string result = ss.str();std::cout << result << std::endl;
}

这里生成了一个包含多个变量值的字符串,变量之间由逗号和空格分隔。

运行结果:

Name: John, Age: 30, Salary: 60000.5

类型转换

使用stringstream将数字转换为字符串

#include <sstream>
#include <iostream>
#include <string>int main() {int num = 123;std::stringstream ss;ss << num; // 将整数放入流中std::string str = ss.str(); // 使用str()函数 从流中提取字符串std::cout << str << std::endl; // 输出:123
}

使用stringstream将字符串转换为数值类型

#include <sstream>
#include <iostream>
#include <string>int main() {std::string str = "456";std::stringstream ss(str); // 初始化stringstreamint num;ss >> num; // 从流中提取整数std::cout << num << std::endl; // 输出:456
}

自动实现数据类型的转换

在 C++ 中,字符串流(stringstream)是一种特殊的流类,它允许将字符串作为输入和输出流进行处理。字符串流提供了一种方便的方式,可以将字符串与其他基本类型进行转换、拼接、解析等操作。

实例:

#include<iostream>
#include<sstream>
using namespace std;
int main() {string s="aaa";stringstream line;line<< s;line << 1;//intline<<0.12; //floatline<<'b'; //charcout<<line.str()<<endl;//结果为:aaa10.12breturn 0;
}

练习

计算字符串中的单词个数

输入:“hello world c plus plus”
输出:5 
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {string str = "hello world c plus plus";int count = 0;stringstream ss(str);string word;while (ss >> word)count++;cout << count << endl;return 0;
}

反转字符串中的单词

151. 反转字符串中的单词

class Solution {
public:string reverseWords(string s) {string res,temp;stringstream ss(s);while(ss>>temp){res = temp + " " + res;}if(!res.empty()){res.pop_back();}return res;}
};

使用 stringstream 实现整数排序

要求把输入保存到在一个stringstream对象中,再这10个整数放到一个整型数组中,将整型数组按大小排序,然后再存回到stringstream对象中。

要使用 stringstream 实现整数排序,你需要按照以下步骤操作:

  1. 初始化一个 stringstream 对象,并用输入的整数填充它。
  2. 将 stringstream 中的整数读取到一个整型数组中。
  3. 对该数组进行排序。
  4. 清空 stringstream 对象并将排序后的整数再放回 stringstream 中。
#include <iostream>
#include <sstream>
#include <algorithm>
#include <iterator>
int main() {// 示例输入,10个整数std::string input = "10 3 5 7 2 8 6 9 1 4";std::stringstream ss(input);// 创建一个足够大的整型数组const int SIZE = 10;int numbers[SIZE];// 从 stringstream 读入整数到数组中for (int i = 0; i < SIZE; ++i) {ss >> numbers[i];}// 对数组进行排序std::sort(numbers, numbers + SIZE);// 清空并重置 stringstreamss.str("");ss.clear();// 将排序后的整数放回 stringstreamfor (int i = 0; i < SIZE; ++i) {ss << numbers[i] << " ";}// 输出结果,展示排序后的数字序列std::cout << "Sorted numbers: " << ss.str() << std::endl;return 0;
}

参考博文:

https://blog.csdn.net/weixin_45867382/article/details/122109133

https://blog.csdn.net/m0_64267361/article/details/135999544

https://blog.csdn.net/weixin_45031801/article/details/136921743

https://blog.csdn.net/m0_75273136/article/details/134712001

https://blog.csdn.net/sinat_28305511/article/details/131237559

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

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

相关文章

java数据结构与算法刷题-----LeetCode268. 丢失的数字

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 数学位运算 数学 解题思路&#xff1a;时间复杂度O( n n n)&…

锐腾授权世强硬创代理导热硅脂等热界面材料,最大化降低界面热阻

随着热界面材料下游新兴应用领域如数据中心、新能源汽车、可穿戴设备等的高速发展&#xff0c;其散热需求也将同步上升&#xff0c;国内热界面材料行业市场规模呈现上涨态势。 在此趋势下&#xff0c;国内锐腾新材料制造&#xff08;苏州&#xff09;有限公司&#xff08;下称…

从零到部署指南:Ubuntu上安装Boost和Crow库

1.安装boost 在安装Crow之前&#xff0c;需要确保您的系统中已经安装了Boost库。以下是Boost库安装步骤&#xff1a; 首先&#xff0c;从Boost官方网站或通过特定的链接下载Boost的源码&#xff0c;boost源码具体可参看这个链接&#xff1a; https://blog.csdn.net/duan199201…

vue3+高德地图+turfjs实现等压线,色斑图(用于显示气象,环境等地图场景)

首先是turf.js(英文官网),也有中文网不过也就目录翻译了一下. 高德官网自行获得key 使用turf的isobands api实现. 数据: 需要准备geojson格式经纬度信息业务值(比如温度,高度,光照只要是number值什么数据都可以) 国内各地区geojson数据点这里获得 参考的是这位大佬写的内容 我…

洛谷 - P1187 3D模型

3D模型 题目描述 一座城市建立在规则的 n m n \times m nm 网格上&#xff0c;并且网格均由 1 1 1 \times 1 11 正方形构成。在每个网格上都可以有一个建筑&#xff0c;建筑由若干个 1 1 1 1 \times 1 \times 1 111 的立方体搭建而成&#xff08;也就是所有建筑的底部…

Unity MySql安装部署与Unity连接 下篇

一、前言 上篇讲到了如何安装与部署本地MySql&#xff1b;本篇主要讲Unity与MySql连接、创建表、删除表&#xff0c;然后就是对表中数据的增、删、改、查等操作。再讲这些之前会说一些安装MySql碰到的一些问题和Unity连接的问题。 当把本地MySql部署好之后&#xff0c;我们可能…

uniapp 小程序获取WiFi列表

<template><view ><button click"getWifiList">获取WiFi列表</button><scroll-view:scroll-top"scrollTop"scroll-yclass"content-pop"><viewclass"itemInfo"v-for"(item, index) in wifiList&…

网络原理(应用层、传输层)

文章目录 一、应用层1.1 自定义协议1.2 通用协议XMLJSONprotobuf 二、传输层2.1 UDP协议2.2 TCP协议协议端格式及解析可靠性机制确认应答超时重传连接管理&#xff08;三次握手&#xff0c;四次挥手&#xff09;流量控制拥塞控制 效率机制滑动窗口延迟应答捎带应答 粘包问题TCP…

3月产品更新来袭,快来看有没你期待的功能

亮点更新一览 增强制作报表易用性&#xff0c;提升用户体验&#xff0c;如仪表盘图层锁定保持原有层级、即席查询支持批量选择表字段。 增强报表展示和分析能力&#xff0c;满足更多项目需求&#xff0c;如仪表盘表格支持配置是否显示分析菜单按钮、Web电子表格新增多选输入…

Unity(MVC思想)

MVC 一下演示使用MVC和不使用MVC的做法区别。 前两个没有使用MVC 主面板逻辑&#xff1a; mainPanel是该脚本名字 每个场景中不一定存在该面板&#xff0c;单纯的显隐需要去手动挂载过于麻烦。 所以自己读取创建面板出来(每个场景仅创建一次)&#xff0c;存下该面板&#xf…

车载平板丨车载数据终端是什么,如何在农机领域发挥作用

车载数据终端是指一种能够获取和处理车辆及其周边环境信息的设备&#xff0c;它集成了GPS导航、行车记录仪、车况诊断、通信等功能&#xff0c;能够实时监测车辆的位置、速度、行驶路线、油耗等数据&#xff0c;为车辆管理和运营提供数据支持。在农机领域&#xff0c;车载数据终…

C++ //练习 11.16 使用一个map迭代器编写一个表达式,将一个值赋予一个元素。

C Primer&#xff08;第5版&#xff09; 练习 11.16 练习 11.16 使用一个map迭代器编写一个表达式&#xff0c;将一个值赋予一个元素。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*************************************…

负荷预测 | Matlab基于TCN-BiGRU-Attention单输入单输出时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-BiGRU-Attention单输入单输出时间序列多步预测&#xff1b; 2.单变量时间序列数据集&#xff0c;采用前12个时刻预测未来96个时刻的数据&#xff1b; 3.excel数据方便替换&#xff0c;运行环境matlab…

Ant Desgin Vue Tree Tab 个性化需求

背景 个人对前端不是很熟&#xff0c;或者说过目就忘&#xff0c;但是对前端还要求不少&#xff0c;这就难搞了。 使用的前端是Mudblazor和ant design vue, Mudblazor 还没有开始搞&#xff0c;现在先用ant design vue&#xff0c;版本是vue3&#xff0c; ant design vue 4版…

OSPF 开放式最短路径优先协议

目录 技术产生原因&#xff1a;因为RIP存在不足 OSPF优点&#xff1a; RIPV2和OSPFV2比较&#xff1a; 相同点&#xff1a; 不同点&#xff1a; OSPF的结构化部署 --- 区域划分 区域划分的主要目的&#xff1a; 区域边界路由器 --- ABR &#xff1a; 区域划分的要求&am…

【静态分析】静态分析笔记03 - 数据流分析(应用)

参考&#xff1a; 【课程笔记】南大软件分析课程3——数据流分析应用&#xff08;课时3/4&#xff09; - 简书 ---------------------------------------------------------------------------- 1. 数据流分析总览 may analysis: 输出可能正确的信息&#xff08;需做 over-…

【感谢】心怀感恩,共赴知识之旅——致每一位陪伴我突破百万总访问量的您

小伙伴朋友们&#xff1a; 此刻&#xff0c;我怀着无比激动与深深感激的心情&#xff0c;写下这篇特别的博文。今天&#xff0c;我的CSDN总访问量成功突破了百万大关&#xff0c;这不仅是一个数字的跨越&#xff0c;更是你们对我的支持、信任与鼓励的有力见证。在此&#xff0…

C语言学习笔记之操作符篇

目录 算术运算符 移位操作符 整型在内存中的存储&#xff08;补充知识&#xff09; ​编辑左移操作符 右移操作符 位操作符 赋值操作符 复合赋值操作符 单目操作符 关系操作符 逻辑操作符 && 与 || 的计算特点 条件操作符 逗号表达式 下标引用操作符 函…

Canal 同步mysql 到es 日期格式报错解决

第一步&#xff1a;下载源码alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 (github.com) 第二步&#xff1a;编辑源码&#xff08;client-adapter下面的clinet-adapter.escore)&#xff1a; com.alibaba.otter.canal.client.adapter.es.core.support.ESSyncUt…

聚丙烯PP它的化学特性是什么? UV胶水能够粘接聚丙烯PP吗?

聚丙烯PP它的化学特性是什么? UV胶水能够粘接聚丙烯PP吗&#xff1f; 聚丙烯&#xff08;Polypropylene&#xff0c;简称PP&#xff09;是一种热塑性聚合物&#xff0c;属于聚烯烃类塑料之一。以下是聚丙烯的一些化学特性&#xff1a; 1. 分子结构&#xff1a; 聚丙烯是由丙烯…