从文件读取大量int值时输出结果不准确该如何解决?
问题分析
- 重复读取文件,指针偏移导致数据跳过:你的代码写了两个独立的for循环,第一个循环先读取了前N条数据(N为你设置的循环次数),完全没有做计算就直接丢弃;第二个循环才开始读取数据做统计,此时文件指针已经移动到第N条数据之后,实际统计的是第N+1到2N条数据。如果你的文件总数据量不足2N条,第二个循环就会读取失败、拿到无效值,这就是你数据跳过、结果错误的核心原因。如果把循环次数调到100,恰好你的文件有超过200条数据,就会碰巧「正常」运行,本质还是逻辑错误。
- 变量未初始化,存在未定义行为:
sum、big两个变量只声明没有初始化,初始值是内存中的随机垃圾值,计算出来的总和、最大值从一开始就是错的。另外small默认初始化为0,如果你的数据全是正数,最终计算出的最小值会一直是0,和实际结果不符。 - 无读取错误校验,无效值参与计算:第二个循环读取数值时没有做失败判断,一旦文件读取到末尾、或者出现格式错误,
number会是不确定的脏值,仍会被加入统计逻辑,进一步导致结果错误。 - 数值溢出风险:10万个int类型值的总和很容易超过32位int的最大取值范围(约21亿),会出现整数溢出,最终总和结果错误。
- 多余的头文件引用:代码中引入了
<cmath>、<iomanip>两个头文件,但完全没有使用相关功能,可以删除。
修复方案
只需要保留一个for循环,边读取边统计即可,修正后的代码如下:
#include <iostream> #include <fstream> #include <climits> // 用于获取int的最大最小边界值 #include <string> using namespace std; int main() { int number; long long sum = 0; // 用long long存总和避免溢出 int big = INT_MIN; // 初始化为int最小值,保证第一个数一定会更新最大值 int small = INT_MAX; // 初始化为int最大值,保证第一个数一定会更新最小值 string file; cout << "Enter a file name: "; cin >> file; ifstream inFile(file); // 新增文件打开失败判断 if (!inFile.is_open()) { cout << "File open failed!" << endl; return 1; } for (long i = 0; i < 100000; i++) { if (!(inFile >> number)) { cout << "Read ERROR at index " << i+1 << "!" << endl; return 1; } // 同一个循环内完成统计 sum += number; if (number < small) { small = number; } if (number > big) { big = number; } } cout << sum << endl; cout << big << endl; cout << small << endl; return 0; }
内容的提问来源于stack exchange,提问作者AJ_
相关产品推荐
相关产品推荐

