fopen文本模式和ftell,fseek的跨平臺問題探討

       當我們使用文本方式打開一個文本文件讀取時,就不應該再使用ftell, fseek函數,因爲這2個函數只適合於二進制模式 ,在文本模式下會因爲系統的不同而產生不同的結果。

典型的文本方式打開比如:

     

FILE *fp = fopen("test.txt", "r");
FILE *fp2 = fopen("test2.txt", "rt");

        嘗試在windows和linux編譯並運行下面的測試程序,這個簡單的程序就是從一個文本文件裏,每次讀取一個字符出來,並用ftell獲取當前的位置:


#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE *fp = fopen("test.txt", "rt");
	char buffer[2];
	int cur;
	for(int i = 0; i < 5; i++)
	{
		fgets(buffer, sizeof(buffer), fp);
		cur = ftell(fp);
		printf("read:%s cur:%d\n", buffer, cur);
	}
	fclose(fp);
	return 0;
}

           要處理的文本文件內容爲:

hello_world

           請注意二進制格式爲:

00000000h: 68 65 6C 6C 6F 5F 77 6F 72 6C 64 0A 0A          ; hello_world..


            Windows運行結果:

read:h cur:-1
read:e cur:0
read:l cur:1
read:l cur:2
read:o cur:3

             Linux運行結果:

read :h cur:1
read :e cur:2
read :l cur:3
read :l cur:4
read :o cur:5

               而且只有在文本換行符使用Linux方式時纔會出現不一致,對於這個問題,微軟的解釋是:

When ftell() is used on a file opened in text mode that contains only linefeeds (0x0A) with no carriage returns (0x0D), ftell() may return an incorrect value on the first call, causing all subsequent return values to be wrong as well. Opening the file in binary mode eliminates this problem. A text file, by definition, contains CR-LF pairs that are condensed to single LF (linefeed) characters on input. A file that contains LF characters with no CR (carriage return) characters is an ill-formed text file and should be processed in binary mode.

            結論就是使用二進制方式讀寫才能保持一致了。

           



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章