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){

nfloatではなく であるからdoubleです。double64 ビットを 32ビットに書き込もうとしているためfloat、すべての賭けが無効になります (未定義の動作)。

標準では、接頭辞はl「次の、、、、、、、、または変換指定子がポインタ型の引数に適用されることを指定する」と述べています。aAeEfFgGdouble

の場合は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 に答える