C++程序中用while循环读取输入文件时遇单行数据异常问题
解决while(!read_file.eof())导致的文件读取异常问题
兄弟,你碰到的是C++文件读取里一个人人都踩过的经典坑——用while(!read_file.eof())控制循环的问题!咱们结合你的情况说清楚:你的输入文件是1 2 2 3,一共4个数值,按道理应该循环两次(每次读一组y[i]和z[i]),但这个循环写法会让程序多跑一次,导致最后一次读取失败,出现莫名其妙的结果。
问题根源
为啥会这样?因为eof()这个标志只有当读取操作尝试越过文件末尾的时候才会被设为true。也就是说,当你读完最后一组数据(2和3)的时候,eof()还是false,循环会继续执行下一次。这时候再执行read_file >> y[i] >> z[i],读取直接失败,但你还是会执行cout输出,这时候y[i]和z[i]要么是之前的残留值,要么是未初始化的垃圾数据,自然就出现了意外。
正确的解决写法
推荐用下面这种最简洁标准的写法,把读取操作直接放在循环条件里:
#include<cassert> #include <iostream> #include <fstream> #include <cmath> using namespace std; int main() { double y[10]; double z[10]; std::ifstream read_file("input.dat"); assert (read_file.is_open()); int i = 0; // 只有读取到有效数据时,才进入循环体 while (read_file >> y[i] >> z[i]) { std::cout << "y[" << i << "] = " << y[i] << " z[" << i << "] = " << z[i] << endl; i++; } read_file.close(); return 0; }
这种写法的逻辑很直观:read_file >> y[i] >> z[i]这个表达式的返回值是流对象本身,当它被用于条件判断时,会自动检查流的状态——只有读取成功(没有到文件末尾、没有读取错误),才会进入循环执行输出和i自增。当读到文件末尾,读取失败,循环直接终止,不会多跑一次。
如果你非要用eof()来写(不推荐,没必要),可以改成这样,先读取再检查状态:
#include<cassert> #include <iostream> #include <fstream> #include <cmath> using namespace std; int main() { double y[10]; double z[10]; std::ifstream read_file("input.dat"); assert (read_file.is_open()); int i = 0; while (true) { read_file >> y[i] >> z[i]; // 读取后立即检查是否失败(包含eof和读取错误) if (read_file.fail()) { break; } std::cout << "y[" << i << "] = " << y[i] << " z[" << i << "] = " << z[i] << endl; i++; } read_file.close(); return 0; }
用正确的写法运行你的输入文件,会得到完全符合预期的输出:
y[0] = 1 z[0] = 2 y[1] = 2 z[1] = 3
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

