C語言學習筆記(4):回車與換行的區別


符號 ASCII 意義
\n 0x0A 換行(LF)
\r 0x0D 回車(CR)

    \r 是return的簡寫,表示光標重新回到本行開頭。其縮寫CR是carriage return就是回車的意思。

    \n 是new line的簡寫,表示光標垂直向下移動一行。其縮寫LF是Line Feed就是換行的意思。

   在計算機還沒有出現之前,有一種叫做電傳打字機(Teletype Model 33,Linux/Unix下的tty概念也來自於此)的玩意,每秒鍾可以打10個字符。但是它有一個問題,就是打完一行換行的時候,要用去0.2秒,正好可以打兩個字符。要是在這0.2秒里面,又有新的字符傳過來,那么這個字符將丟失。
   於是,研制人員想了個辦法解決這個問題,就是在每行后面加兩個表示結束的字符。一個叫做“回車”,告訴打字機把打印頭定位在左邊界;另一個叫做“換行”,告訴打字機把紙向下移一行。這就是“換行”和“回車”的來歷,從它們的英語名字上也可以看出一二。
   后來,計算機發明了,這兩個概念也就被般到了計算機上。那時,存儲器很貴,一些科學家認為在每行結尾加兩個字符太浪費了,加一個就可以。於是,就出現了分歧。
   Unix系統里,每行結尾只有“<換行>”,即"\n";

   Windows系統里面,每行結尾是“<換行><回車>”,即“\r\n”;

   Mac系統里,每行結尾是“<回車>”,即"\n";。

   一個直接后果是,Unix/Mac系統下的文件在 Windows里打開的話,所有文字會變成一行;而Windows里的文件在Unix/Mac下打開的話,在每行的結尾可能會多出一個^M符號。

    於是,進行測試,分別在win10和ubuntu系統中新建文本文檔寫入兩行文字:第一行為123456789,第二行為987654321。然后在win10系統中打開兩個文本,發現win10自己創建的文件是分為兩行顯示的,沒有問題。Ubuntu生成的文件在win10中顯示為1行。接下來在Ubuntu中打開兩個文件,發現兩個文件均換行。接下來在win10系統中通過UltraEdit打開,查看兩個文件的ASCII碼,如下:

win10中生成的文件:

win

Ubuntu中生成的文件:

linux

    從結果可以看出,正如上面所說,Unix系統中,每行結尾只有”\n”;windows系統中每行結尾是”\r\n”。

    還沒結束,接下來說一說在C語言編程中的”\n”,因為這里與上面說的又有不同。

#include <stdio.h>
#include <math.h>
#include <stdio.h>

FILE *fp;

void main()
{
    fp = fopen("p1.txt","wb");

    fprintf(fp, "123456789\n987654321");

    fclose(fp);

    return;
}

如上代碼,fopen函數中,參數"wb"表示只寫打開或新建一個二進制文件;只允許寫數據。根據上面所提到的\n意義,我們推斷在win10中,打開生成的txt文件,應該僅輸出一行。實際情況也確實如此。接下來,我們把fopen中的參數改為fopen("p1.txt","wx");其余代碼全不變,這里"wx"表示創建文本文件,只允許寫入數據。其結果發現生成的txt中,存在兩行,也就是說"\n"一個符號就完成了win10中的換行命令。這說明在C語言中輸出文檔時,若采用二進制編碼輸出文件,函數會嚴格按照給定字符串的編碼來進行輸出;但是如果設定輸出文檔時以文本形式輸出,函數會自動將\n解析為\r\n,從而輸出兩行文本。這一點在控制台程序中也有體現:

#include <stdio.h>

void main()
{
    printf("Hello World!\n");
}

上面的代碼顯然會換行,並在第二行輸出:Press any key to continue

再啰嗦一些,如果把第一段代碼中fprintf(fp, "123456789\n987654321");改為fprintf(fp, "123456789\r\n987654321");並且采用"wx"輸出,會怎么樣呢?

嗯!首先肯定是會換行的。然后,我們參看它的ASCII,發現\r\n在文本中並不是像預期的那樣是0D 0A而是0D 0D 0A:

這也說明了,在這里代碼中的"\n"被fprintf函數解析輸出為"\r\n"。當然如果在linux系統下執行這個程序,應該是會把"\n"僅解析為"\n"的。

嗯,然后也可以測試一下fprintf(fp, "123456789\r987654321");在"wb"和"wx"情況下的輸出文本結果。嗯是完全一樣的:123456789987654321

但是,如果在控制台上輸出結果,例如:printf("123456789\r987654321");實際輸出結果為:987654321,說明"\r"起作用,控制台先輸出123456789,然后,"\r"使光標移動到最前方,輸出987654321,將原來的輸出覆蓋。


免責聲明!

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



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