一、概览与类体系
c++ 提供三种基于内存字符串的流,定义在 <sstream> 中:
- std::istringstream:输入流,从已有字符串中读取并解析。
- std::ostringstream:输出流,向内部缓冲区写入内容,最终取回为字符串。
- std::stringstream:读写流,兼具 istringstream 和 ostringstream 的功能。
它们都继承自 std::basic_iostream<char>
,可使用所有流操作符与格式化工具。
二、常见用法
1. 构造与取出字符串
std::ostringstream oss; // 默认空缓冲 oss << "value=" << 42 << ", pi=" << std::fixed << std::setprecision(3) << 3.14159; // 获取结果 std::string s = oss.str(); // s == "value=42, pi=3.142"
- str():获取当前缓冲区的字符串。
- str(const std::string&):重置缓冲区内容。
2. 字符串解析
std::string line = "123 45.6 ok"; // 将 line 内容作为流缓冲 std::istringstream iss(line); int a; double b; std::string status; // 按空白自动切分并转换 if (iss >> a >> b >> status) { // a==123, b==45.6, status=="ok" } // 检查是否完全消费或错误 if (iss.fail() && !iss.eof()) { // 转换中发生格式错误 }
- 运算符>> 会跳过空白,并尝试按目标类型解析。
- 解析失败时,流会置
failbit
,后续操作将不中断程序,除非打开异常模式。
3. 读写混合
std::stringstream ss; ss << "x=" << 10 << ";y=" << 20; // 重设读写位置到开头 ss.seekg(0); // 逐字符读取、跳过标识 char ch; int x, y; ss >> ch >> ch >> x; // 假设格式 "x=10" ss >> ch >> ch >> y; // 跳过 ";y="
- seekg/seekp 可重定位读/写指针,方便混合使用。
- 在写完后若要读,通常要 ss.seekg(0);同理,由读转写可用 ss.seekp(0, std::ios::end)。
三、格式控制与状态检查
格式化:与标准流一致,可用 <iomanip> 中的操纵器,如 std::hex、std::setw、std::setfill、std::boolalpha、std::fixed、std::scientific 等调整输出格式。
状态位:用 good()、fail()、eof()、bad()、rdstate() 检测流状态;用 clear() 重置。
异常模式:
iss.exceptions(std::ios::failbit | std::ios::badbit); try { int v; iss >> v; // 解析失败即抛异常 } catch (const std::ios_base::failure& e) { // 处理错误 }
默认不会抛。
四、性能与注意事项
- 避免频繁 str() 调用:每次
str()
都会拷贝缓冲区字符串,影响性能。可在最后一次取用时再调用。 - 预分配缓冲:可用
ss.str().reserve(n)
或先构造带初始字符串的stringstream
,减少动态分配。 - 切换格式后状态保留:如果你在一个流上设置了某个格式(如
std::hex
),它会一直生效, remember to reset(std::dec
)。 - 注意空白和分隔:
>>
默认以空白分隔,解析整行或含空格的字段时要用std::getline
。 - 多语种/宽字符:对于 unicode 或宽字符流请使用
std::basic_stringstream<wchar_t>
。
五、综合示例
#include <iostream> #include <sstream> #include <iomanip> int main() { // 构建字符串 std::ostringstream oss; oss << "point(" << std::setw(2) << std::setfill('0') << 7 << "," << std::fixed << std::setprecision(1) << 3.14 << ")"; std::string desc = oss.str(); // "point(07,3.1)" std::cout << desc << "\n"; // 解析回数值 std::istringstream iss(desc); char ch; int ix; double dy; if ( (iss >> ch >> ch >> ix >> ch >> dy >> ch).good() ) { std::cout << "parsed: x=" << ix << ", y=" << dy << "\n"; } else { std::cerr << "parse error\n"; } // 读写混合:累加偏移 std::stringstream ss("100 200 300"); int sum = 0, v; while (ss >> v) sum += v; // sum=600 std::cout << "sum=" << sum << "\n"; return 0; }
小结
- std::ostringstream:安全构建复杂字符串/格式化输出。
- std::istringstream:高效拆解、解析已知格式的文本。
- std::stringstream:读写一体,用于需要往返操作的场景。
- 始终关注流状态和格式保留,并合理管理缓冲与性能。
掌握这些知识,你就能在日志构建、文本解析、动态内容生成等场景中,灵活高效地运用 c++ 的字符串流。
到此这篇关于c++中string流的具体使用的文章就介绍到这了,更多相关c++ string流内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论