2

まず、私は C は初めてですが、プログラミングはしていません。私はPHPで多くのWeb開発を行っています。質問に...

一連のバイナリ ファイルを読み取ってコンテンツを出力する関数がありますが、使用するとsprintf()、後続の多次元配列のメモリ割り当てに影響します。下記参照:

FILE *fp;

for(int i = 1; i <= 16; i++) {

    char format_1[] = "track_%d.bin";
    char filename_1[sizeof format_1+100];
    sprintf(filename_1,format_1,i);
    printf("Filename: %s \n", filename_1);
    fp = fopen(filename_1, "rb");

    if(fp) {
        fseek(fp, 0L, SEEK_END);
        int sz = (ftell(fp) / 3) - 1;
        fseek(fp, 0L, SEEK_SET);

        printf("File size: %d\n", sz);

        int nums[sz][3];

        fread(nums,sizeof(int),sz * 3, fp);

        for (int k = 0; k < sz; k++) {
            printf("Entry number %d = %d with extra values of %d and %d\n", k, nums[k][0], nums[k][1], nums[k][2]);
        }
    } else {
        printf("Skipping \n");
    }

    fclose(fp);
}

関数を次のように単純化したため、問題の原因は sprintf() であることはわかっています。

printf("Please enter file number... \n");
scanf("%d%c", &num_file, &term);

printf("Please enter how many instances in this file... \n");
scanf("%d%c", &num_instance, &term);

int nums[num_instance][3];

char format_1[] = "track_%d.bin";
char filename_1[sizeof format_1+3];
sprintf(filename_1,format_1,num_file);
printf("Filename: %s \n", filename_1);

fp = fopen(filename_1, "rb");

fread(nums,sizeof(int),num_instance * 3, fp);
fclose(fp);

for (int k = 0; k < num_notes; k++) {
    printf("Entry number %d = %d with extra values of %d and %d\n", k, nums[k][0], nums[k][1], nums[k][2]);
}

nums の宣言を sprintf() の上に移動すると、nums の宣言を sprintf() の下に移動するとすぐに (そのすぐ上にある場合でも) 正常に動作します。出力は次のようになります。

Entry number: 0 = 71 with extra values 116 and 158
Entry number: 1 = -1073743712 with extra values -1073744240 and -1073744304
Entry number: 2 = -1073743896 with extra values 59983 and -1073744005

上のコード スニペットからわかるように、ファイル内のエントリ数を知る必要があるため、nums以下の宣言が必要です。sprintf()

編集:ファイルに多次元配列が含まれていることを言及すると役立つと思います: array[x][3].

これに本当に困惑しています。どんな助けでも大歓迎です。

4

1 に答える 1

2

あなたの基本的な問題は、ファイルのサイズをバイト単位で計算し、ファイルからその多くの整数を読み取ろうとすることです。整数は (ほとんどのマシンで) 4 バイトであるため、これは失敗し、nums配列の最初の 4 分の 1 しか読み取れません。残りの部分にはランダムなガベージが含まれます (そして出力されます)。

の戻り値をチェックしfreadて、意味があることを確認する必要があります。コードを次のように変更すると

int numread = fread(nums,sizeof(int),sz * 3, fp);
printf("Read %d integers from file\n", numread);
for (int k = 0; k < sz; k++) {
    if (k < numread/3) {
        printf("Entry number %d = %d with extra values of %d and %d\n", k, nums[k][0], nums[k][1], nums[k][2]);
    } else {
        printf("Entry number %d doesn't exist in the file\n", k);
    }
}

問題はすぐにわかります。

常に戻り値を確認してください。

于 2013-04-03T23:33:53.930 に答える