C++17中如何避免stringstream读带尾空白行时的循环多余迭代?
解决带尾空白行的数字重复读取问题
你的代码问题出在用peek()判断循环条件,但未检查数字读取是否成功:当行尾有空白时,peek()会先返回空白字符(而非EOF),触发循环迭代;执行lineStream >> n时,流会跳过所有空白直到遇到EOF,此时读取操作失败,流进入错误状态,但n的值不会被更新(未初始化时是垃圾值,初始化后是你设置的0),最终导致输出无效的重复值。
最优解决方案(简洁惯用写法)
直接利用>>运算符的特性:它会自动跳过所有空白(空格、换行、制表符等),且当无法读取有效整数时(比如流末尾、非数字字符),会返回流对象的错误状态,以此作为循环条件即可完美处理所有空白场景:
#include <iostream> #include <sstream> int main() { std::string line = "1 2 "; // 带尾空白的测试行 std::stringstream lineStream(line); int n; // 只要读取有效整数,就继续循环 while (lineStream >> n) { std::cout << "n==" << n << "," << std::flush; } return 0; }
兼容原循环结构的修改方案
如果要保留原有的peek()循环逻辑,只需在读取数字后检查流的状态,若读取失败则直接跳出循环:
#include <iostream> #include <sstream> int main() { std::string line = "1 2 "; std::stringstream lineStream(line); for (char nextChar = lineStream.peek(); nextChar != EOF; nextChar = lineStream.peek()) { int n; lineStream >> n; // 检查读取是否成功,失败则终止循环 if (!lineStream) { break; } std::cout << "n==" << n << "," << std::flush; } return 0; }
两种方案都能正确处理"1"、"1 2"、"1 2 "等所有输入情况,其中第一种是C++处理此类场景的标准写法,代码更简洁且不易出错。
内容的提问来源于stack exchange,提问作者Michael T
相关产品推荐
相关产品推荐

