/ / fread - c ++を使ってゴミを生産する

fread - c ++を使ってゴミを生産する

私はfreadを使ってデータを読みたいと思いますファイル。しかし、私はNULLターミネータの設定の問題に遭遇しました。私は行(fileMem [fileSize] = 0;)が解決されているはずだと思います。しかし、私はまだ "fileMem"の値をチェックすることでゴミを得る。誰も私が問題を見つけるのを助けるだろうか?

私は、NULLターミネーターの設定についての他の投稿をたどってきましたが、うまくいきません

File *input = fopen(filePath, "r");
fseek(input, 0, SEEK_END);
auto fileSize = ftell(input);
fseek(input, 0, SEEK_SET);
char* fileMem = new char[fileSize+1];
fileMem[fileSize] = 0;// the NULL terminator problem should have been solved here
clearerr(input);
fread(fileMem, fileSize,1, input);

私のコードの問題は何ですか?

回答:

回答№1は1

freadはfileSizeよりも多くのバイトを読み込んでいますが、fileSizeのレコードサイズを指定し、1つのテキストレコードだけを読み込むように要求しているためです。そして最後に0が実際のデータで上書きされるので、ゴミが出ます。

freadは実際に読み込んだバイト数を返すので、より大きなバッファを割り当ててから、freadの戻り値を使ってどれだけ有効であるかを判断し、ヌルターミネータを設定します。

この方法でデータを更新しているので、ファイルタイプをバイナリ(fopenの呼び出しで "r"ではなく "rb")に変更することもお勧めします。

これが起こっている理由は、freadが、キャリッジリターンや改行などのテキストモード( "rb"ではなく "r")でテキストの翻訳を実行するためです。


回答№2の場合は1

あなたがWindows上にいると仮定すると、問題はあなたがテキストモードでファイルを開き、 fread これはバイナリモードを意味します。 テキストモードでは、読み込んだ内容がファイル内の内容と正確に異なる場合があります。 Windowsのテキストファイルはファイルの最後に "rn"を持ちますが、テキストモードではこの2つの文字の組み合わせが1文字の "n"に変換されます。だから fileSize 計算した値が大きすぎるため、ヌルターミネータが間違った場所に置かれます。

これを確認するには、 fread することが:

int nr = fread( fileMen, 1, fileSize, input);

中間の引数を交換すると、 fread 読み取られたバイト数を返します。の価値を見れば nr、それはより小さくなります fileSize 行末の翻訳のために。

これはテキストモードでの変換がないので、* nixシステムでは問題にはなりません。


回答№3の場合は0

あなたが使いたいとき fread ファイルの内容を読み取るには、バイナリモードでファイルを開く必要があります。

FILE *input = fopen(filePath, "rb");
^^

それ以外の場合は、

fseek(input, 0, SEEK_END);
auto fileSize = ftell(input);

文字の数よりも大きくなります。 fread.

CRとLFがある場合、上記の方法では2文字とカウントされますが、 fread 1文字のみを読み込みます。したがって、 fread 未満を読み取る fileSize 文字。また、 fread 行に:

// Swap the middle arguments.
// The first argument is supposed to be the size of each object.
// The second argument is supposed to be the number of objects to read.
auto n = fread(fileMem, 1, fileSize, input);
if ( n != fileSize )
{
// Surprise
}
fileMem[n] = "";