C++中string流知识详解和示例

一、概览与类体系

C++ 提供三种基于内存字符串的流,定义在 <sstream> 中:

  • std::istringstream:输入流,从已有字符串中读取并解析。
  • std::ostringstream:输出流,向内部缓冲区写入内容,最终取回为字符串。
  • std::stringstream :读写流,兼具 istringstreamostringstream 的功能。

它们都继承自 std::basic_iostream<char>,可使用所有流操作符与格式化工具。


二、常见用法

1. 构造与取出字符串

cpp 复制代码
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. 字符串解析

cpp 复制代码
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. 读写混合

cpp 复制代码
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)

三、格式控制与状态检查

  1. 格式化 :与标准流一致,可用 <iomanip> 中的操纵器,如 std::hexstd::setwstd::setfillstd::boolalphastd::fixedstd::scientific 等调整输出格式。

  2. 状态位 :用 good()fail()eof()bad()rdstate() 检测流状态;用 clear() 重置。

  3. 异常模式

    cpp 复制代码
    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>

五、综合示例

cpp 复制代码
#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++ 的字符串流。

相关推荐
Simple_core15 分钟前
qt3d自定义生成mesh图形
开发语言·qt·3d
SundayBear37 分钟前
适合有C基础后快速上手C++
开发语言·c++
顾三殇1 小时前
【自考】《计算机信息管理课程实验(课程代码:11393)》华师自考实践考核题型解析说明:C++ 与 mysql 实践题型与工具实践题分析
c++·mysql·华师自考实践考核题型分析
l1o3v1e4ding1 小时前
python-docx 库教程
开发语言·python·c#
酷爱码1 小时前
Python虚拟环境与Conda的使用方式详解
开发语言·python·算法
newki1 小时前
【NDK】项目演示-Android串口的封装工具库以及集成的几种思路
android·c++·app
whoarethenext1 小时前
使用 C++ 和 OpenCV 构建智能答题卡识别系统
开发语言·c++·opencv
Epiphany.5561 小时前
堆排序code
数据结构·c++·算法
m0_516484672 小时前
C#winform多选框代码
开发语言·c#
Dfreedom.2 小时前
Excel文件数据的读取和处理方法——C++
c++·数据分析·excel·数据预处理