C語言中以文本方式讀寫文件時換行符轉換的注意事項


我們知道在UNIX下是沒有回車符(\r)的,只有換行符(\n),而C語言誕生於UNIX(Linux即面向開源的UNIX,Mac OS也是UNIX發展而來的,而Windows是從MS-DOS發展而來,與前兩者不同),所以C語言的源代碼文件中也是以 \n 表示換行。

所以總結一下:

Windows下換行采用 \r\n 表示,全稱回車換行符。

UNIX(Linux)下換行采用 \n 表示,即換行符。

Mac OS下換行采用 \r 表示,即回車符。

 

所以,當C語言在Windows下以文本方式讀取文件就會出現一個轉換,看如下代碼:

FILE * f1;
f1 = fopen("utf8.txt", "r");
/*
    "utf8.txt"文件的十六進制結構如下:
    41 42 43 0D 0A 44 44 4B
*/
fseek(f1, 3, SEEK_SET);
printf("%x\n", getc(f1));
printf("%x\n", getc(f1));
fclose(f1);

輸出結果:

a
44
Press any key to continue

解釋:當我們把文件指針通過fseek函數移到位置 3 時,文件指針指向了回車符(0x0D),然后我們用getc函數讀取當前文件指針所指的字節時,C語言會把Windows下表示換行的0x0D和0x0A兩個字節看成UNIX下表示換行的0x0A一個字節,所以,此時getc函數返回的是0x0A這個值。故,這次的getc函數讀完后文件指針向后偏移兩個字節,導致了下一個的getc返回的是0x44。

同理,當C語言在Windows下工作時,用putc向文件輸入 \n 時會被自動轉成 \r\n,如下代碼:

FILE * f1;
f1 = fopen("new.txt", "w");
putc('\n', f1);
fclose(f1);

"new.txt"文件的十六進制結構:

0D 0A

解釋:上述代碼會在當前目錄創建一個新文件"new.txt",並以文本方式只寫模式打開文件流,然后通過putc向該文件輸入字符 \n,這時C語言會自動把 \n 轉為 \r\n,原理同上。

注意的是:C語言是否自動轉換 \n 與 \r\n 取決於編譯C語言程序時所在的系統,也同理在Mac OS下,C語言會自動發生 \n 與 \r的轉換。

當然,這種情況是不會發生轉換的:

FILE * f1;
f1 = fopen("utf8.txt", "r");
/*
    該文件的十六進制結構如下:
    31 32 33 0A 0D
*/
fseek(f1, 3, SEEK_SET);
printf("%x\n", getc(f1));
printf("%x\n", getc(f1));
fclose(f1);

輸出結果:

a
d
Press any key to continue

解釋:因為只有在Windows下編譯的C程序,並且以文本方式打開一個文件,並且讀取的0x0D后面緊跟着0x0A才會發生轉換,也就是說0x0D 0x0A兩個字節必須作為一個整體出現,顯然,上述代碼例子顛倒了 \r\n 的順序。

另外,在Mac OS下編譯的C程序,以文本方式讀取一個以 \n 表示換行的文件時,也是不會發生 \r 與 \n的轉換的,只有該文件以 \r 表示換行時才會發生 \r 與 \n的轉換。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM