0

次のようなデータを含む複数のテキストファイルがあります。

    0.000000E+0 0.000000E+0
    1.800000E-1 0.000000E+0
    4.200000E-1 0.000000E+0
    6.950000E-1 0.000000E+0
    9.450000E-1 0.000000E+0
    1.225000E+0 0.000000E+0

これはテスト機器によって生成されました。データの2つの列は、タブ文字で区切られています。このデータファイルをプログラムに読み込んでさらに処理しようとしています。私が書いたコードは次のとおりです。

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

float **make_array(int size); //function to make 2D array

int main(int argc, char **argv)
{
        FILE *infile;
        infile=fopen(argv[1], "r");

//count number of lines in file
        char c;
        int i=0, numlines=0;
        while((c=fgetc(infile))!=EOF)
                if(c == '\n') numlines++;

        printf("numlines: %d\n", numlines);

        float **entry = make_array(numlines);

//read inputfile
        for(i=0; i< numlines; i++)
                fscanf(infile, " %G\t%G", &entry[0][i], &entry[1][i]);
//verify read values
        printf("\n");
        for(i=0; i<numlines; i++)
                printf("%E\t%E\n", entry[0][i], entry[1][i]);

//clean up before exiting
        free(entry[0]);
        free(entry[1]);
        free(entry);
        fclose(infile);
return 0;
}


//create a 2D array of 2 by {size}
float **make_array(int size){
        int i;
        float **entry = malloc(2*sizeof(float *));
        if(entry==NULL) exit(1);
        entry[0] = malloc(size*sizeof(float *));
        for(i=0;i<size;i++) entry[0][i] == 0.0;
        entry[1] = malloc(size*sizeof(float *));
        for(i=0;i<size;i++) entry[1][i] == 0.0;

return entry;
}

プログラムをコンパイルして実行すると、ファイルの行数が正しく出力されますが、配列に読み込まれたデータを確認するprintfステートメントはentry、次のようにすべてゼロを出力します。

numlines: 252

0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00

fscanflikeに対してさまざまな形式指定子を試しまし%g,%e,%f,%G etcたが、すべて同じ結果になります。また、GCC4.6でUbuntu12.04を使用しています。何が悪いのかへのポインタは大歓迎です。

ハディージャ。

4

3 に答える 3

4

最初のループ:

while((c=fgetc(infile))!=EOF)
    if(c == '\n') numlines++;

入力ファイル全体を読み取ります(配列のサイズを決定するため)。これを実行すると、すでにファイルの最後にいるため、すべての呼び出しはfscanf失敗します。

入力ファイルがシーク可能であると仮定すると(ディスクファイルの場合はそうなるはずです)、rewind()またはfseek()を使用して最初に戻り、もう一度読み取ることができます。

ところで、フォーマット指定子の使用%G%E有効ですが%g%eより一般的です(まったく同じように機能するはずです)。

argcそして、あなたは本当に参照する前にの値をチェックする必要がありますargv[1]; コマンドライン引数なしで呼び出された場合、プログラムは爆発する可能性があります。fopen()また、成功したかどうかを確認する必要があります。これにより、2がfscanf()返され、2つのデータ項目が正常に読み取られたことを示します。

于 2012-06-28T20:44:21.120 に答える
1

したがって、問題は次のとおりです。

while((c=fgetc(infile))!=EOF)
            if(c == '\n') numlines++;

そのwhileループを実行した後、FILE *はEOFを指しているため、次のようになります。

for(i=0; i< numlines; i++)
            fscanf(infile, " %G\t%G", &entry[0][i], &entry[1][i]);

すべてのfscanfはEOFを返し、値をまったくスキャンしません。

于 2012-06-28T20:54:23.643 に答える
0

キースは問題を指摘しましたが、他に考えるべきことがいくつかあります。

  • fscanf;の結果を確認してください。成功した変換と割り当ての数が返されます。2未満に戻った場合は、データを正しく読み取っていません。

  • andのmalloc呼び出しで間違ったデータ型を使用しています。ではなく、を使用する必要があります。書くことで物事を片付けることができます-こうすれば、そのような種類の型の不一致はありません。 entry[0]entry[1]sizeof (float)sizeof (float *)entry[0] = malloc(sizeof *entry[0] * size);

  • ファイルを2回読み取ることは非効率的で、不要です。とにかく配列を動的に割り当てているので、ファイルを読んでいるときにサイズを拡張して使用することができ entry[0]ますentry[1]realloc

于 2012-06-28T20:55:32.223 に答える