0

ファイルから変数を読み取るプログラムを作成するように指示するCプログラミングクラスの練習問題をやっています。最初の行では、整数 N を読み込むことになっています。

そこから、整数を読み取り、N 行ごとに各行で 5 つの浮動小数点を読み取る必要があります。ファイル内のすべての float の合計を計算し、それを別のファイルに書き込むことになっています。

fgets を使用して行を文字列にコピーし、sscanf を使用してそれを分析し、セグメントを別の配列の場所に割り当てるプログラムを作成しました。ただし、sscanf (おそらく null 値または改行) を介して無関係な情報を取得する際に問題が発生しています。整数 N が適切に格納されておらず (大きなランダム値が生成され、無限ループによって実行時エラーが発生しています)、おそらくループ内でも機能していません。

整数と浮動小数点数を適切に読み込むようにするにはどうすればよいですか?

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

#define MAX_STRING 30
#define MAX_LINE_SIZE 200

int main(void)
{
    FILE *f1, *f2;
    char filename[MAX_STRING];
    char fileline[MAX_LINE_SIZE];
    int N, eN;
    float totalwage = 0;
    int* ssn;
    float** wage;

    printf ("Enter a file name for data analysis: ");
    scanf ("%s", &filename); //get file name from user input for reading

    f1 = fopen (filename, "r");

    fgets (fileline, MAX_LINE_SIZE, f1); //read first line
    sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow

    for (eN = 0; eN < N; eN ++) //read N lines following the first
    {
        // VVV read single line from file
        fgets (fileline, MAX_LINE_SIZE, f1);
        // VVV record data from line
        sscanf (fileline, "%d, %f, %f, %f, %f, %f", &ssn[eN], &wage[eN][0], &wage[eN][1], &wage[eN][2], &wage[eN][3], &wage[eN][4]);
        // VVV add the 5 wages on each line to a total
        totalwage += wage[eN][0] + wage[eN][1] + wage[eN][2] + wage[eN][3] + wage[eN][4];
    }

    fclose (f1);

    printf ("Enter a file name for the result: ");
    scanf ("%s", &filename); //get file name from user input for writing

    f2 = fopen (filename, "w");

    fprintf (f2, "%f", totalwage); //store total of wages in file specified by user

    printf ("\nThe information has been stored. Press any key to exit.\n");
    getchar();
}

読み取られるファイルは「wages.txt」で、その内容は次のとおりです。

10
1, 10, 20, 30, 40, 50
2, 11, 12, 13, 14, 15
3, 21, 23, 25, 27, 29
4, 1, 2, 3, 4, 5
5, 30, 60, 90, 120, 150
6, 37, 38, 39, 40, 41
7, 40, 50, 60, 70, 80
8, 5, 10, 15, 20, 25
9, 80, 90, 100, 110, 120
10, 1000, 2000, 3000, 4000, 2000

要約すると、問題は、ある種の無限ループが原因でプログラムがクラッシュするランタイム エラーがあることです。いくつかのデバッグを通じて、最初の行を整数として適切に読み取っていないことがわかりました。値 10 の代わりに、null 文字を読み取ったかのように大きな値を格納していました。


ssn と賃金にメモリを割り当てるためのコードを追加しました。ただし、それが正しく行われたかどうかはわかりません。また、プログラムにはまだクラッシュするランタイム エラーがあります。

ssn = malloc (N*MAX_STRING);
wage = malloc (N*MAX_STRING);
for (eN = 0; eN < N; eN ++)
{
    wage[eN] = malloc (N*MAX_STRING);
}
4

3 に答える 3

3

賃金にメモリを割り当てていません。float へのポインターへのポインターとして宣言されます。それは問題ありませんが、ポインターはどこも指していません。

ssnも同じです。

この行の後:

sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow

ssnとwage用にメモリを割り当てる必要があります。

これは宿題なので、メモリの割り当て方法については説明しません。あなたはそれを自分で理解できる必要があります。

于 2013-11-09T06:49:24.420 に答える
0

他の人が指摘したように

scanf ("%s", &filename);

次のようにする必要があります。

scanf ("%s", filename);

sscanf列の数が変わると大きな問題になることに注意してください

で使用するために改訂strtod:

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

#define MAX_STRING 30
#define MAX_LINE_SIZE 200
#define COLS 5

int main(void)
{
    FILE *f1, *f2;
    char filename[MAX_STRING];
    char fileline[MAX_LINE_SIZE];
    int N, eN, i;
    float totalwage = 0;
    float (*wage)[COLS];
    char *p;

    printf ("Enter a file name for data analysis: ");
    scanf ("%s", filename); //get file name from user input for reading
    f1 = fopen (filename, "r");
    fgets (fileline, MAX_LINE_SIZE, f1); //read first line
    sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow
    wage = malloc((sizeof(float) * COLS) * N);
    /* check malloc ... */
    for (eN = 0; eN < N; eN ++) //read N lines following the first
    {
        // VVV read single line from file
        p = fgets (fileline, MAX_LINE_SIZE, f1);
        strtol(p, &p, 10); /* skip first column */
        for (i = 0; i < COLS; i++) {
            wage[eN][i] = strtod(p + 1, &p); /* p+1 skip comma, read a float */
            totalwage += wage[eN][i]; /* sum */
        }
    }
    free(wage);
    fclose (f1);
    printf ("Enter a file name for the result: ");
    scanf ("%s", filename); //get file name from user input for writing
    f2 = fopen (filename, "w");
    fprintf (f2, "%f", totalwage); //store total of wages in file specified by user
    printf ("\nThe information has been stored. Press any key to exit.\n");
    getchar();
    fclose(f2); /* you forget to close f2 */
    return 0;
}

また、フロートは合計のみを読み取っているため、保存する必要がないため、malloc回避できることに注意してください。実際にはfopenfgets...の結果を確認してください。

于 2013-11-09T07:40:21.400 に答える
0

1 つの float を格納するためにメモリを割り当てる場合、float 値は 4 バイトで構成されることを理解する必要があるため、malloc を呼び出すときは、これを考慮して 1 つの float を格納する必要があります: intmalloc( sizeof(float ) )の float の配列サイズ N を格納するには、malloc( N*sizeof(float ) )sizeof(int)

于 2013-11-09T07:52:04.907 に答える