簡體   English   中英

使用fread產生垃圾

[英]Produce garbage with using of 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);

我的代碼有什么問題?

fread讀取的字節數大於fileSize,因為您要指定fileSize的記錄大小,並要求它僅讀取一個文本記錄。 然后,它將最后用實際數據覆蓋0,因此會出現垃圾。

fread返回它實際讀取的字節數,因此您可以分配更大的緩沖區,然后使用fread的返回值確定其中有多少有效(並設置一個空終止符)。

由於它是以這種方式更新數據的,因此我還建議將文件類型更改為二進制(在fopen調用中為“ rb”而不是“ r”)。

發生這種情況的原因是因為fread在文本模式(“ r”而不是“ rb”)下執行文本翻譯,例如回車和換行。

假設您使用的是Windows,我認為問題在於您正在以文本模式打開文件,並使用了意為二進制模式的fread 在文本模式下,您讀取的內容可能與文件中的內容不完全相同。 Windows文本文件在文件末尾帶有“ \\ r \\ n”,但是在文本模式下,這兩個字符的組合將轉換為單個字符“ \\ n”。 因此,您計算出的fileSize太大,因此您的空終止符將放在錯誤的位置。

為了驗證這一點,將fread更改為:

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

交換中間的args,將使fread返回讀取的字節數。 如果查看nr的值,由於行尾轉換,它將小於fileSize

在* nix系統上這不是問題,因為在文本模式下沒有翻譯。

當您想使用fread讀取文件的內容時,必須以二進制模式打開文件。

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

否則,您通過使用得到的文件的大小

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

將大於fread可以讀取的字符數。

如果您有CR和LF,按照上述方法,它們將被視為兩個字符,但是fread只會讀取一個字符。 因此, 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] = '\0';

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM