std::stringstream
是C++标准库中的一个类,用于在内存中操作字符串流。它提供了一种方便的方式来格式化和解析字符串数据,类似于文件流(如 std::ifstream
和 std::ofstream
)但针对字符串。std::stringstream
属于 <sstream>
头文件,结合了输入(std::istringstream
)和输出(std::ostringstream
)的功能。
1.基本功能
- 格式化输出:可以像使用
std::cout
一样向std::stringstream
写入数据,然后将其作为字符串读取。 - 字符串解析:可以将一个字符串传递给
std::stringstream
,并从中解析不同的数据类型。 - 内存中的流操作:不涉及文件操作,完全在内存中进行数据的格式化和解析。
2.常见用法
构造和赋值
#include <sstream>
#include <string>int main() {// 创建一个空的 stringstreamstd::stringstream ss;// 用字符串初始化 stringstreamstd::string initialData = "123 456";std::stringstream ss2(initialData);
}
写入数据
#include <sstream>
#include <iostream>int main() {std::stringstream ss;int num = 42;std::string text = "Hello, World!";// 向 stringstream 写入数据ss << num << " " << text;// 获取生成的字符串std::string result = ss.str();std::cout << "Generated string: " << result << std::endl;return 0;
}
读取数据
#include <sstream>
#include <iostream>int main() {std::string data = "123 456.789 Hello";std::stringstream ss(data);int i;float f;std::string s;// 从 stringstream 读取数据ss >> i >> f >> s;std::cout << "Integer: " << i << std::endl;std::cout << "Float: " << f << std::endl;std::cout << "String: " << s << std::endl;return 0;
}
清空和重用
#include <sstream>
#include <iostream>int main() {std::stringstream ss;ss << "Initial text";std::cout << "Before clearing: " << ss.str() << std::endl;// 清空内容并重用ss.str("");ss.clear();ss << "New text";std::cout << "After clearing: " << ss.str() << std::endl;return 0;
}
3.常见的操作
str()
:获取或设置stringstream
中的字符串。clear()
:重置流的状态标志。seekg()
和seekp()
:调整流中读写指针的位置。
#include <sstream>
#include <iostream>int main() {std::stringstream ss("1234");// 读取第一个字符char c;ss >> c;std::cout << "First char: " << c << std::endl; // 1// 移动读指针到起始位置ss.seekg(3);// 读取第一个字符ss >> c;std::cout << "First char after seekg: " << c << std::endl; // 4return 0;
}
4.适用场景
- 字符串拼接和格式化:代替
sprintf
或手动字符串拼接操作,更加类型安全。 - 解析复杂字符串:从一个字符串中提取并解析多个数据字段。
- 内存中的流处理:无需文件I/O操作,适合处理小型数据或临时数据。
5.示例:解析复杂字符串
#include <sstream>
#include <iostream>int main() {std::string data = "42 3.14 Hello World";std::stringstream ss(data);int integer;float real;std::string firstWord, secondWord;ss >> integer >> real >> firstWord >> secondWord;std::cout << "Integer: " << integer << std::endl;std::cout << "Float: " << real << std::endl;std::cout << "First word: " << firstWord << std::endl;std::cout << "Second word: " << secondWord << std::endl;return 0;
}
7. 线程安全
std::stringstream
不是线程安全的。如果多个线程同时访问同一个 std::stringstream
对象,必须使用适当的同步机制(如互斥锁)来防止数据竞争和不一致。
8. 相关类
std::istringstream
:只支持输入操作的字符串流。std::ostringstream
:只支持输出操作的字符串流。std::fstream
、std::ifstream
、std::ofstream
:文件流,用于处理文件的I/O操作。
总结
std::stringstream
是一个强大的工具,用于在内存中处理字符串数据。它提供了灵活的格式化和解析功能,适合在需要频繁进行字符串操作的应用场景中使用。相比传统的C风格字符串操作,std::stringstream
提供了更安全和更便捷的接口,有助于提高代码的可读性和维护性。
具体例题例子
string discountPrices(string sentence, int discount) {double d = 1 - discount / 100.0;stringstream ss(sentence);string ans, w;while (ss >> w) { // 一边分割,一边加到答案中if (!ans.empty()) {ans += ' ';}if (w.length() > 1 && w[0] == '$' && all_of(w.begin() + 1, w.end(), ::isdigit)) {stringstream s;s << fixed << setprecision(2) << '$' << stoll(w.substr(1)) * d;ans += s.str();} else {ans += w;}}return ans;
}
解释:
std::fixed
:
- 操作流,使其以定点表示法输出浮点数。
- 输出的浮点数总是保留固定的小数位数(由
std::setprecision
指定)。 - 如果
std::setprecision
设置了整数部分小数点后的位数,将用0填充不足的位数。
std::setprecision
:
- 用于设置浮点数输出时的小数精度。
- 其效果取决于当前流的浮点格式模式(例如,
std::fixed
或std::scientific
)。 - 在
std::fixed
模式下,std::setprecision
控制小数点后的位数。
举例
显示两位小数
#include <iostream>
#include <iomanip>int main() {double pi = 3.141592653589793;std::cout << std::fixed << std::setprecision(2) << pi << std::endl; // Output: 3.14return 0;
}
与其他格式操纵符对比
std::scientific
:- 将浮点数以科学计数法输出。
- 通常用于处理非常大或非常小的数值。
#include <iostream>
#include <iomanip>int main() {double value = 12345.6789;std::cout << std::scientific << std::setprecision(2) << value << std::endl; // Output: 1.23e+04return 0;
}