这是一个从文件中读取未知数量的整数并计算平均值的函数。由于某种原因,文件中的最后一个元素被读取两次。有人可以解释一下原因吗?我知道如何修复它,但想知道幕后发生了什么。
int total = 0, count = 0, input;
FILE *filePtr;
filePtr = fopen("file.txt", "r");
if (filePtr != NULL)
do
{
fscanf(filePtr, "%d", &input);
total = total + input;
count++;
} while (!feof(filePtr));
printf ("%d", total);
我通过在循环中放置第二个if
来修复它:
do
{
fscanf(filePtr, "%d", &input);
if (!feof(filePtr))
{
total = total + input;
count++;
}
} while (!feof(filePtr));
答案 0 :(得分:3)
您没有检查fscanf
是否确实找到了号码。最后一次调用将失败,因为您最有可能只是读取文件中的最后一个换行符。
试试这个:
do
{
if (fscanf(filePtr, "%d", &input)==1) {
total = total + input;
count++;
}
} while (!feof(filePtr));
编辑: @Andrew是对的 - 您应该在循环顶部检查EOF:
while (!feof(filePtr)) {
/* ... */
}
答案 1 :(得分:3)
看起来您不应该使用do-while loop
。基本上,您正在从文件中读取,然后检查文件末尾。如果有0 ints
怎么办?在检查文件是否在最后之前,您将尝试阅读。
另外,您没有检查fscanf
的结果。它会报告它是否成功......
答案 2 :(得分:1)
do-while
结构导致此副作用,因为它首先读取数据,因此在执行循环内的代码之后立即检查条件。尝试使用while
结构以避免两次读取最后一项,您将不再需要在循环内执行if
测试。
while (!feof(filePtr)){
fscanf(filePtr, "%d", &input);
total = total + input;
count++;
}
答案 3 :(得分:1)
: “请注意,流的内部位置指示器可能指向下一个操作的文件结尾,但是,在操作尝试读取该点之前,可能不会设置文件结束指示符。”
因此即使您读取文件中的最后一个int指针指示EOF,但由于没有人再次尝试读取,因此feof并不表示文件已到达。
我认为相同的值是'读两次',因为变量没有改变,并且它与最后读取的值保持相同的值。