1

ショートパンツの単一のブロックを割り当て、それをファイルにfwriteしてから、読み戻そうとしています。しかし、ファイルに書き込まれるデータは、出力されるデータと一致しません。問題を次のコードに切り分けました。私が間違っていることについて何か考えはありますか?

#define CHUNK_SIZE 1000
void xwriteStructuresToFile(FILE *file, void * structureData)
{
    assert((fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE);

}

void wwbuildPtxFiles(void)
{   
    FILE *file = fopen("s:\\tv\\run32\\junky.bin", WRITE_BINARY);
    int count = 10;
    short *ptx = (short *) calloc(CHUNK_SIZE * count, sizeof(short ) );

    memset(ptx, '3', sizeof(short) * CHUNK_SIZE * count);
    for (int dayIndex = 0; dayIndex < count; ++dayIndex)
        xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);

    free(ptx);
    fclose(file);

    file = fopen("s:\\tv\\run32\\junky.bin", READ_BINARY);
    int xcount = CHUNK_SIZE * count * sizeof(short );
    for (int i = 0; i < xcount; ++i)
    {
        char x;
        if ((x = getc(file)) != '3')
            assert(false);
    }
}
4

5 に答える 5

2

配列インデックスからsizeof(short)を削除します。Cがあなたに代わってこの計算を行います

于 2012-02-14T05:35:39.293 に答える
1

への呼び出しではxwriteStructuresToFile、次を使用します。

&ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]

ptxは短いポインタです。つまり、配列の計算は自動的に短いサイズにスケールアップされます。

上記の式でもこれを明示的に行うことで、配列の終わりをはるかに超えて移動しています。その行を次のようなものに置き換える必要があります。

xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);
于 2012-02-14T05:33:59.443 に答える
1

配列の末尾を超えて「データ」を書き込んでいます!

xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);

以下を使用する必要があります。

xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);

C コンパイラはsizeof(short)自動的にスケーリングします。整数の配列がある場合、配列の i番目のメンバーarray[i * sizeof(int)]にアクセスするようには記述しません。同様に、ここではインデックスを でスケーリングする必要はありません。確かに、そうしないことは非常に重要です。なぜなら、( と仮定して) メモリを予想どおりに 2 回書いているからです。sizeof(short)sizeof(short) == 2

assert()また、実行する必要がある関数呼び出しの周りで使用しないでください。assert()機能に影響を与えずにプログラムから省略できる別のステートメントで使用します。これについては、Steve Maguire による「Writing Solid Code」である程度詳しく説明されています。これは、少し古くなっていますが、少なくともこの点では適切です。

于 2012-02-14T05:39:40.433 に答える
1

いくつかのこと:

ファイルを開く方法、定数についてはわかりませんが、読む必要があります

"wb"バイナリファイルの書き込みと"rb"読み取り。

assert にステートメントを入れないでください。プログラムがリリース モードでコンパイルされると、assert は削除されます。代わりに、戻り値を確認し、それをアサートします

例えば


bool ok =fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE;
assert(ok);

これについてアサートするべきではありませんが、代わりに適切なエラー メッセージを出力する必要があります。assert はランタイム エラーではなく、プログラミング エラー用です。


short *ptx = (short *) calloc(CHUNK_SIZE * count, sizeof(short ) );

上記の行にはいくつかの問題が含まれています。

  • の戻り値をcallocCでキャストしないでください。short *ptx = calloc...警告が表示された場合は、十分なはずです。#include <stdlib.h>

  • calloc( count, CHUNK_SIZE * sizeof( short ));そうしないと少し不明確に見えるフォームを使用する必要があります。( calloc は数値、サイズを引数として取ります)


   for (int dayIndex = 0; dayIndex < count; ++dayIndex)
      xwriteStructuresToFile(file, 
         (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);

そこで何をしているのかわからない場合は、2 つのステートメントを次のように置き換えます。


fwrite( ptx, CHUNK_SIZE * sizeof( short ), count, fp );


配列全体を書き込む必要があります。

于 2012-02-14T06:15:30.787 に答える
0

ptxはポインタであるため、インデックスを作成するときにshort *乗算しないでください。sizeof(short)インデックスはすでにsの単位であるshortため、次のようにします。

xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * dayIndex ]);
于 2012-02-14T05:34:37.587 に答える