我們知道在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的轉換。