2

我正在尝试从与 Unix 平台上的当前目录不同的目录中读取文本文件“P1-Data”,并创建 GPA 数组以使用 C 语言计算平均 GPA。

这是名为“P1-Data”的文本文件:

    Mark Bhatia 852600012  3.23
    Larry Burch 123236399  2.94
    Howard Huge 234123456 3.00
  # Andrew Jackson 123321123 4.00
    Lee David 666656666 3.02
    Norden Bruce 432156978 3.75
    Price Jones 121256435 2.75
    Rountree Travis 123123132 2.89
    Volek Volek 101100100 3.05
  # Fine Students 000000121 4.0
    John Bhatia 952600012  3.93
    Jangla House 123457890 2.03 
  # Tee David 666656667 3.42
  # Moriarty Hodges 898888999 2.04
    Wonder Druce 332156978 3.78
    Price Hones 121256435 2.75
    Flattree Travis 123123134 3.95
    Drew Pete 101100101 3.05

它位于目录:home/.../class1/.../.../P1-DATA

这是名为“stage1.c”的 C 代码,它给了我错误(用 Notepad++ 编写):

    #include <stdio.h>
    #include <math.h>

    int main(int argc, char* argv[]){

    int i = 0;
    float sum = 0.00, n = 0.00, avg = 0.00;

    FILE *fin;

    fin = fopen("P1-DATA", "r");

    // Keep reading in integers (which are placed into "n") until end of file (EOF)
    while(fscanf(fin, "%lf", &n) != EOF){
    // Add number to sum
    sum += n;

    // Increment counter for number of numbers read
    i++;

    // Average is sum of numbers divided by numbers read
    avg = (sum / i);
    }

    // After the loop is done, show the average
    printf("The average is %lf.\n", avg);

    fclose(fin);

    return 0;
    }

这位于目录:home/.../class2/s/name/.../stage.c(主要点不同的目录

我还注意到,我在尝试打开的文件名中放入什么并不重要。我仍然遇到分段错误。所以我想在那之前我错过了一些东西。也许我需要切换到“P1-DATA”文件所在的目录??如果是这样..我不确定如何在 C 中做到这一点。任何帮助将不胜感激。另外,我的日程安排有点紧……这只是我需要做的第一部分。提前致谢!

4

2 回答 2

4

你对这条线有一个严重的问题:

while(fscanf(fin, "%lf", &n) != EOF){

因为n是 afloat而不是 a double。因为您正在尝试将 64-bitdouble写入 32-bit float,所以所有赌注都已关闭(未定义的行为)。

该标准规定,l前缀“指定……后面a的 , A, e, E, f, F, g, 或G转换说明符适用于类型指针指向double“的参数。

对于 a float,您应该只使用%f. 或者你可以把你所有的浮点类型都变成double——我很少再使用这种float类型了。


此外,检查使用它们指示错误的函数的返回值(连同errno)被认为是一种很好的做法。如果fopen失败,fin则将设置为NULL,然后尝试使用它来读取数据将是一个坏主意。就像是:

#include <errno.h>
:
fin = fopen("P1-DATA", "r");
if (fin == NULL) {
    printf ("Error %d opening input file\n", errno);
    exit (1);
}

会做。有更友好的方法可以做到这一点,但这至少会让你知道是否发生了错误以及错误是什么。


根据您的评论,这会给您一个错误代码 2 (ENOENT),这是因为该文件不存在。您需要运行程序时位于数据文件所在的目录中,或者在fopen.

于 2012-09-22T02:20:27.133 回答
1

您可以将其指定为命令行参数,而不是在代码中指定数据文件的名称。

#include <err.h>
#include <stdio.h>

if (argv[1] == NULL)
    err(1, "usage: %s datafile", argv[0]);

if ((fin = fopen(argv[1], "r")) == NULL)
    err(1, "Could not open \"%s\"", argv[1]);

(注意从fopen()上面检查返回值。)

然后,您可以使用数据文件的路径作为命令行参数调用您的程序:

% ./a.out /path/to/the/data/file

另请注意,您的数据文件似乎比简单的浮点数列表具有更多的结构。尝试使用简单的"%f"格式字符串解析该数据不太可能奏效。

于 2012-09-22T03:14:40.513 回答