至此,所有 I/O 示例均写入 cout 或从 cin 读取。然而,标准库还提供了一组字符串流类,允许使用熟悉的插入运算符 << 与提取运算符 >> 直接对字符串进行操作。与 istream / ostream 类似,字符串流内部维护一个缓冲区来保存数据;但与 cin / cout 不同,这些流并不连接到键盘、显示器等物理 I/O 通道。它们最常见的用途是:
- 先缓冲输出,稍后统一显示;
- 逐行处理输入数据。
字符串流共有六个类:
- istringstream、- ostringstream、- stringstream(分别派生自- istream、- ostream、- iostream)——用于窄字符(- char)字符串。
- wistringstream、- wostringstream、- wstringstream——用于宽字符(- wchar_t)字符串。
使用字符串流需包含头文件 <sstream>。
向字符串流写入数据的两种方式
- 使用插入运算符 <<:
std::stringstream os{}; os « “en garde!\n”; // 将 “en garde!” 写入流
2. 使用成员函数 `str(string)` 直接设置缓冲区内容:  
   ```cpp
std::stringstream os{};
os.str("en garde!");   // 把缓冲区设为 "en garde!"
从字符串流读取数据的两种方式
- 使用成员函数 str()获取整个缓冲区内容:
std::stringstream os{}; os « “12345 67.89\n”; std::cout « os.str(); // 输出:12345 67.89
2. 使用提取运算符 `>>`:  
   ```cpp
std::stringstream os{};
os << "12345 67.89";     // 将数字串写入流
std::string strValue{};
std::string strValue2{};
os >> strValue >> strValue2;   // 依次提取
std::cout << strValue << " - " << strValue2 << '\n';
// 输出:12345 - 67.89
注意:
- >>会按提取顺序遍历流——每次调用返回下一个可提取值;
- str()则返回流中完整内容,不受先前提取影响。
字符串与数值之间的转换
由于插入/提取运算符支持所有基本数据类型,可借此完成字符串与数值的互转。
数值 → 字符串:
std::stringstream os{};
constexpr int nValue{ 12345 };
constexpr double dValue{ 67.89 };
os << nValue << ' ' << dValue;
std::string strValue1, strValue2;
os >> strValue1 >> strValue2;
std::cout << strValue1 << ' ' << strValue2 << '\n';
// 输出:12345 67.89
字符串 → 数值:
std::stringstream os{};
os << "12345 67.89";   // 将数字串写入流
int nValue{};
double dValue{};
os >> nValue >> dValue;
std::cout << nValue << ' ' << dValue << '\n';
// 输出:12345 67.89
重用字符串流前先清空
清空字符串流缓冲区有多种方法:
- 用空 C 字符串:
std::stringstream os{}; os « “Hello “; os.str(””); // 清空缓冲区 os « “World!”; std::cout « os.str(); // World!
2. 用空 `std::string` 对象:  
   ```cpp
std::stringstream os{};
os << "Hello ";
os.str(std::string{}); // 清空缓冲区
os << "World!";
std::cout << os.str(); // World!
两段代码输出均为:
World!
清空字符串流后,通常还应调用 clear() 以重置可能存在的错误标志:
std::stringstream os{};
os << "Hello ";
os.str("");  // 清空缓冲区
os.clear();  // 重置错误标志,使流恢复到正常状态
os << "World!";
std::cout << os.str();
clear() 会清除所有错误标志,确保后续操作正常进行。下一课将详细介绍流状态与错误标志。
