2

这是一个从文件中读取未知数量的整数并计算平均值的函数。由于某种原因,文件中的最后一个元素被读取了两次。有人可以解释为什么吗?我知道如何解决它,但想知道幕后发生了什么。

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));
4

4 回答 4

3

You're not checking that fscanf actually finds a number. The last call will fail because you're most likely just reading in the last line break in the file.

Try this:

do
{
    if (fscanf(filePtr, "%d", &input)==1) {
        total = total + input;
        count++;
    }
} while (!feof(filePtr));

EDIT: @Andrew is right — you should really check for an EOF at the top of the loop:

while (!feof(filePtr)) {
    /* ... */
}
于 2013-10-30T11:42:19.117 回答
3

看起来你不应该使用do-while loop. 基本上,您正在从文件中读取然后检查文件结尾。如果有 0ints怎么办?在检查文件是否在末尾之前,您将尝试阅读。

此外,您没有检查fscanf. 它报告它是否成功......

于 2013-10-30T11:44:02.730 回答
1

The do-while structure cause this side effect, because it first reads the data, so the condition is checked just after the code inside the loop is executed. Try to use the while structure to avoid reading the last item twice, you will no longer need to do the if test inside the loop.

while (!feof(filePtr)){
    fscanf(filePtr, "%d", &input);
    total = total + input;
    count++;
}
于 2013-10-30T11:42:12.450 回答
1

来自feof 文档:“请注意,流的内部位置指示符可能指向下一个操作的文件结尾,但在操作尝试在该点读取之前,可能不会设置文件结尾指示符。”

因此,即使您读取文件中的最后一个 int,指针也会指向 EOF,但是因为没有人尝试再次读取 feof 并不表示已到达文件末尾。

我认为相同的值是“读取两次”,因为变量没有改变,并且它与最后一次读取的值相同。

于 2013-10-30T11:50:58.343 回答