【问题标题】:calculating average of values from a CSV file in C从 C 中的 CSV 文件计算值的平均值
【发布时间】:2015-01-08 17:22:56
【问题描述】:

我正在编写一个代码,我在其中读取一个 CSV 文本文件,该文件在命令行中作为参数给出。我必须计算给定文件的实验平均值:
例如,如果文件是

Bob's experiment,12,33,55,8
Mary's experiment,99,21,12,0

我必须打印出来 Bob 的实验(数字的平均值) 玛丽的实验(平均数)

这是我的代码:

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

int main (int argc, char *argv[]){
FILE* ptr=fopen(argv[1], "rt");
int i=0;
double sum=0;
double count=0;
double ave=0;
if (ptr==NULL){
    perror("Error while opening file");
    exit(EXIT_FAILURE);   
}
while(!feof(ptr)){
                char s='a';
                while(s!=','){
                             s=fgetc(ptr);
                              printf("%c", s);
                  }
                while((char) *ptr)!='\n'){
                                    fscanf(ptr, "%d", &i);
                                    sum+=i;
                                    count++;
                  }
                    ave=sum/count;
                    printf("%.2f", ave);
            }
        fclose(ptr);
}

}

我得到一个奇怪的无限循环类型的结果。 请告诉我我做错了什么!

}

【问题讨论】:

  • 这看起来很可疑:while(((char) *ptr)!='\n')。取消引用指向 FILE 的指针,然后尝试将其与字符进行比较似乎是不正确的。
  • 还有前面的while -- 如果文件中没有逗号或换行符会怎样?
  • 你知道我该如何解决它吗?
  • 对于最后一个 while 循环,我试图在指针尚未到达行尾时进行 while 循环说明
  • FILE * 不是指向文件内容的指针——它只是一个文件句柄。您必须阅读内容(例如使用fgetcfscanf),然后才能根据它们做出任何决定。

标签: c file csv average fileparsing


【解决方案1】:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main (int argc, char *argv[]){
    FILE* ptr=fopen(argv[1], "rt");
    double sum, count, ave;
    int i=0;

    if (ptr==NULL){
        perror("Error while opening file");
        exit(EXIT_FAILURE);
    }
    while(1){
        int s;
        while((s=fgetc(ptr)) != ',' && s != EOF){
            printf("%c", s);
        }
        if(s == EOF)
            break;
        printf("\t");
        count = sum = 0;
        while(1==fscanf(ptr, "%d%*c", &i)){//%*c skip ',' and '\n'
            sum += i;
            count++;
        }
        ave = sum / count;
        printf("%.2f\n", ave);
    }
    fclose(ptr);
    return 0;
}

【讨论】:

    【解决方案2】:

    正如上面的评论所暗示的,您从 FILE* 指针检查字符值的语法是无效的。您可以将 ((char) ptr* != '\n') 替换为 (fgetc(ptr) != '\n')


    另外说明,像这样使用双嵌套循环进行解析通常是糟糕的设计,并且很难调试。无限循环可能是由许多极端情况引起的(例如,在您阅读最后一行之后?)。我建议每个案例都有一个带有条件的while循环,例如:

    while(!feof(ptr)) {
        char s = fgetc(ptr);
        if(s == '\n') {
           ...
        } else if(s == ',') {
           ...
        } else {
           ...
        }
    
    }
    

    多个循环只会增加复杂性,因此最好避免。


    如果您绝对必须使用上述算法,您可以编写安全措施来检测超时,例如:

    int timeout = 0;
    while(s!=',' && timeout < 500) {
        ...
        timeout++;
    }
    if(timeout >= 500) {
       printf("First loop timeout, s:%c\n", s);
       ... some other useful state checking if you wish..
    }
    

    这样您就可以轻松检测到哪个循环正在进入无限循环,并确定此时变量的状态。

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多