C++中含尾空白的整数流读取时最后一个整数重复输出问题
C++读取带尾空格文本时重复输出最后一个整数问题解决
问题场景
现有名为input.txt的文本文件,内容为空格分隔的整数,每行均带有尾空格,示例内容如下:
2 3 4 1 5 4 1
为区分每行,使用getline读取内容,编写的C++代码如下:
int main() { string input; stringstream ss; ss.clear();ss.str(""); int no_lines = 3; int tmp; for(int i = 0; i < no_lines; i++) { getline(cin, input); ss.clear(); ss.str(input); while(!ss.eof()) { ss >> tmp; cout << tmp << ' '; } cout << endl; } }
执行命令a.out < input.txt运行程序,预期输出与input.txt内容一致,但实际输出如下:
2 3 3 4 1 1 5 4 1 1
每行最后一个整数被重复输出。
问题原因
核心问题是**while(!ss.eof())的判断逻辑错误**。当ss >> tmp读取到行尾空格后,会尝试读取下一个整数,此时已到达流末尾,eof()标志位才会被置为true。但最后一次ss >> tmp操作已经失败,tmp的值并未更新,仍保留上一次读取的最后一个整数,随后执行cout << tmp << ' '就会重复输出该旧值。
以第一行"2 3 "为例:
- 第一次
ss >> tmp读取到2,输出2; - 第二次读取到3,输出3;
- 第三次尝试读取,遇到行尾空格后到达流末尾,
ss >> tmp失败,但此时while(!ss.eof())的判断仍为true(eof标志未触发),进入循环体后输出了之前的3,之后ss.eof()变为true,循环结束。
解决方案
方法一:直接判断读取操作是否成功
将循环条件改为ss >> tmp,因为>>操作符返回流对象本身,读取失败时流对象会被转为false,循环自动终止:
int main() { string input; stringstream ss; int no_lines = 3; int tmp; for(int i = 0; i < no_lines; i++) { getline(cin, input); ss.clear(); ss.str(input); while(ss >> tmp) { cout << tmp << ' '; } cout << endl; } }
方法二:读取后检查流状态
若需保留eof()判断,可在读取后立即检查流是否有效,无效则跳出循环:
int main() { string input; stringstream ss; int no_lines = 3; int tmp; for(int i = 0; i < no_lines; i++) { getline(cin, input); ss.clear(); ss.str(input); while(!ss.eof()) { ss >> tmp; if(!ss) break; cout << tmp << ' '; } cout << endl; } }
冗余代码优化
原代码中初始化阶段的ss.clear();ss.str("");属于冗余代码,因为每次循环都会重新调用ss.clear()和ss.str(input),可以直接删除。
内容的提问来源于stack exchange,提问作者Yahia Ghadiry
相关产品推荐
相关产品推荐

