なぜ恐怖はEOFに早く到達するのですか?
質問
ファイルをメモリに読み込むCライブラリを書いています。ファイル(ヘッダー)の最初の54バイトをスキップし、残りをデータとして読み取ります。 fseekを使用してファイルの長さを特定し、freadを使用してファイルを読み取ります。
ループは1回実行され、EOFに到達した(エラーなし)ため終了します。最後に、bytesRead = 10624、ftell(stream)= 28726、およびバッファには28726の値が含まれています。 EOFに達すると、freadは30,000バイトを読み取り、ファイル位置は30054になると予想しています。
Cは私の母国語ではないので、どこかでバカな初心者の間違いがあると思います。
コードは次のとおりです。
const size_t headerLen = 54;
FILE * stream;
errno_t ferrno = fopen_s( &stream, filename.c_str(), "r" );
if(ferrno!=0) {
return -1;
}
fseek( stream, 0L, SEEK_END );
size_t bytesTotal = (size_t)(ftell( stream )) - headerLen; //number of data bytes to read
size_t bytesRead = 0;
BYTE* localBuffer = new BYTE[bytesTotal];
fseek(stream,headerLen,SEEK_SET);
while(!feof(stream) && !ferror(stream)) {
size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-bytesRead,stream);
bytesRead+=result;
}
使用する参照に応じて、「b」を追加することは非常に明白です。モードフラグへの答えです。骨頭バッジのノミネートを求めています。 :-)
このリファレンスは、2番目の段落の2番目の文で説明しています。 (ただし、テーブルにはありません)。
MSDN はバイナリについて説明していませんページの半分までフラグを立てます。
OpenGroup は、「b」の存在を言及しています。タグですが、「効果がない」と述べています。
解決
おそらくバイナリモードの問題です。モードとして" r + b"
でファイルを開いてみてください。
編集:コメント" rb"
に記載されているように、" r + b"
読み取り/書き込み用に開き、" rb"
は読み取り専用です。
他のヒント
リンクコマンドにbinmode.objを含めるだけで、すべてのファイルを開くときにこれが実行されることに注意してください。
以前の回答に基づく解決策:
size_t bytesRead = 0;
BYTE* localBuffer = new BYTE[bytesTotal];
fseek(stream,headerLen,SEEK_SET);
while(!feof(stream) && !ferror(stream)) {
size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-
bytesRead,stream);
bytesRead+=result;
}