fread函數讀取到的數據和實際數據不同

背景

最近項目中弄個接口,涉及到二進制文件處理,剛開始對讀寫文件夾這塊沒有太注意,結果最後浪費了一些時間。函數

文件大小600+k(不到一兆),二進制存儲,總長度638208個字節,以下:spa

正文

最初,經過fopen打開文件,以下:.net

/* 打開文件*/
if((fp_input = fopen(strFilePath.GetBuffer(), "r")) == NULL)
{
    MessageBox("Can't open intput file!");
}

而後獲取文件的總長度,以下:code

/* 獲取文件總長度(總字節數) */
long filesize(FILE *stream)
{
	long curpos, length;

	curpos = ftell(stream);
	fseek(stream, 0L, SEEK_END);
	length = ftell(stream);
	fseek(stream, curpos, SEEK_SET);
	return length;
}

一切看似都很正常,文件能打開,總長度獲取也沒問題,而後就是經過fread讀取文件內容了,以下:blog

/* 讀取文件內容 */
if(fread(str_file, 1, flength, fp_input) == 0)
{
    MessageBox("Can't read file!");
	return;
}

OK,下面就開始根據接口格式解析文件內容了。接口

問題也就出來了,明明文件總長度爲638208個字節,但每次處理到629000+個字節後程序就崩掉了。開始我覺得是我解析代碼裏面內存沒處理好形成內存溢出了,而後我就把全部分配內存的地方註釋掉,發現還有問題。調了一段時間後,我就在函數入口的地方直接偏到629000+的位置看了內存裏面的內容,發現居然爲空。如今就定位了問題出在前面的讀文件,往前看代碼,發現fopen的時候用的「r」,改爲「rb」,從新跑了下程序。OK了,OK了,OK了,爲何?內存

爲何用「r」和「rb」都能讀取文件內容,但讀出來的東西卻不同了?get

帶着疑問,在網上搜了一把(以前確實沒注意過這個問題,也沒遇到過),發現真有這樣的問題,緣由以下:input

先看一段MSDN:

If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value.

就是說若是按「文本模式」打開一個文件,那麼在讀入的時候,Windows默認的換行符CR+LF就會轉換成一個單個的LF。it

引自:https://blog.csdn.net/tgdzsjh/article/details/32702073

r遇到0x0d後面沒有0x0a會自動加一個,遇到0x1a會忽略後面的內容
rb不會

r 讀到\r\n會改成\n,讀到\x1a會返回EOF
rb 讀到什麼返回什麼,讀到文件末尾纔會返回EOF

引自:https://blog.csdn.net/cattylll/article/details/7107089

相關文章
相關標籤/搜索