为什么C++的stringstream无法读取新增数据?流行为解析
理解C++ stringstream的复用问题
我是C++新手,编写了如下代码,无法理解stringstream的行为。请注意:我已解决该问题,不需要规避方案,只想理解流的行为。
代码
void solve() { string nl = "\n"; string color; string line; string piece; cin >> color; cout << color << nl; cin.ignore(); // ignores the space getline(cin, line); stringstream ss(line); while(getline(ss, piece, ',')) { cout << piece << " " << piece.size() << nl; } cin >> color; cout << color << nl; cin.ignore(); // ignores the space getline(cin, line); ss << line; while(getline(ss, piece, ',')) { cout << piece << " " << piece.size() << nl; } }
输入内容
White: Ke1,Qd1 Black: Ke8,Qd8
输出结果
White: Ke1 3 Qd1 3 Black:
可见输出中,Black:之后没有打印棋子信息。我认为ss << line第二次未生效,预期该行会将新字符追加到ss流中,之后可读取,但实际并非如此。我通过新建stringstream对象解决了问题,但想复用第一个对象,希望理解我的认知误区。
问题原因解释
核心问题是第一次读取完stringstream后,流的状态已经处于“EOF(文件结束)”状态,直接往里面写数据并不会重置这个状态,后续读取操作会直接失败。
具体细节:
- 第一次执行
while(getline(ss, piece, ','))循环时,会一直读取到流的末尾,此时ss的eofbit标志被置位,标记流已读完。 - 执行
ss << line时,数据确实会写入到stringstream的底层缓冲区,但流的eofbit状态不会自动清除。 - 第二次调用
getline(ss, piece, ',')时,流检测到eofbit已被设置,会直接返回读取失败,循环根本不会执行。
如果想要复用这个stringstream对象,需要在写入新数据前手动重置流状态并清空缓冲区:
// 在 ss << line; 之前添加这两行 ss.clear(); // 清除所有错误状态标志(包括eofbit) ss.str(""); // 清空底层的字符串缓冲区
执行这两步后,流会回到初始可用状态,写入新数据后就能正常读取了。
内容的提问来源于stack exchange,提问作者ashish singh
相关产品推荐
相关产品推荐

