2014-01-19 304 views
0

我有号码的列表在我*.txt文件:如何从文件中读取数字并计算平均值?

1 2 
3 

称为numbers.txt。我需要阅读它们并计算平均值,对于我的文件,它将是:(1 + 2 + 3)/3 = 2;虽然我的代码显示了一些错误的结果,但它读了两次。为什么呢,如何解决它?

我的代码:直到读传文件的末尾尝试从测试feof()测试fscanf()

while(fscanf(f, "%lf", &tmp) != EOF) { 
    printf("tmp = %f \n", tmp); 
    sum += tmp; 
    ++ i; 
} 

feof(f)

#include <stdio.h> 
#include <stdlib.h> 

double fun(const char *filename) 
{ 
    double sum = 0, mean = 0, tmp = 0; 
    int i = 0; 
    FILE *f; 
    if((f = fopen(filename, "r")) == NULL) 
    { 
     exit(-1); 
    } 

    while(!feof(f)) 
    { 
     fscanf(f, "%lf", &tmp); 
     printf("tmp = %f \n", tmp); 
     sum += tmp; 
     ++ i; 
    } 

    i = i - 1; 
    mean = sum/i; 

    fclose(f); 

    printf("i = %d\n", i); 
    printf("sum = %f\n", sum); 
    printf("mean = %f\n", mean); 

    return mean; 
} 

int main(int argc, char **argv) 
{ 
    fun("numbers.txt"); 

    return 0; 
} 

回答

3

变化是不正确的。因此,前面的呼叫fscanf(f, "%lf", &tmp)在OP的原始代码中返回EOF,而不是更新tmp。所以tmp似乎是3两次。


正如@BLUEPIXY指出的那样,i = i - 1;是不需要的。如果有任何测试if (i==0)可以添加为罕见的情况下没有输入。

+0

最好的解决办法是'int cnt; while((cnt = fscanf(f,“%lf”,&tmp)!= 1){'Then test'cnt'.EOF'表示EOF或IO错误,0表示未能转换为'double',1:表示1次成功转换。 – chux

+0

括号中的数字在前面的注释中未对齐。 – BLUEPIXY

4

你实际上并没有读取3两次。

问题是,在最后一个数字(3)之后,还有其他字符,即空格。所以,EOF标志在读取最后一个数字后不会出现,并且while循环进入另一次迭代。 fscanf未读取任何值,但前一个值仍在tmp中,该值将被再次处理。

你应该做的是检查返回值fscanf,它会告诉你实际扫描和转换参数的数量。它应该是1,因为您正在尝试扫描一个变量。修复您的代码:

while(!feof(f)) 
{ 
    if (fscanf(f, "%lf", &tmp) != 1) { 
     // No numbers 
     break; 
    } 

    printf("tmp = %f \n", tmp); 
    sum += tmp; 
    ++ i; 
} 

并删除i = i - 1。你必须编写它来补偿循环比预期多一次的事实。

2

它被读两次,因为feof(f)再次进入循环的次数超过了你的预期。

在这种情况下,在读取任何数据之前调用feof(),所以它返回false。循环被输入,fgetc()被调用(并返回EOF),count递增。然后调用feof()并返回true,导致循环中止。