【C++】stringstream

2024-04-12 11:04
文章标签 c++ stringstream

本文主要是介绍【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

这篇关于【C++】stringstream的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

2024/9/8 c++ smart

1.通过自己编写的class来实现unique_ptr指针的功能 #include <iostream> using namespace std; template<class T> class unique_ptr { public:         //无参构造函数         unique_ptr();         //有参构造函数         unique_ptr(