回車和換行

peterjxl發表於2024-06-15

在學計算機的時候,總是會遇到回車和換行,但一直沒去深究;在學習字元編碼相關知識的時候,覺得得深入去搞懂下,除了編碼,在我們日常工作中也是經常會遇到的。

因此去網上查閱了相關部落格,有了今天這篇文章。我們先從回車和換行的起源說起

起源:打字機

在計算機還沒有出現之前,有一種叫做電傳打字機(Teletype Model 33,Linux/Unix 下的 tty 概念也來自於此)的玩意,每秒鐘可以打 10 個字元。但是它有一個問題,就是打完一行換行的時候,要用去 0.2 秒(注:估計是從打字機的最右邊回到最左邊的機械運動 所需要的時間),正好可以打兩個字元。要是在這 0.2 秒裡面,又有新的字元傳過來,那麼這個字元將丟失。

於是,研製人員想了個辦法解決這個問題,就是在每行後面加兩個表示結束的字元

一個叫做 “回車(Carriage Return) ”,告訴打字機把列印頭定位在左邊界;注意,並沒有移動到下一行的意思。

另一個叫做 “換行(Line Feed) ”,告訴打字機把紙向下移一行。

這就是 “換行” 和 “回車” 的來歷,從它們的英語名字上也可以看出一二。

也就是回車和換行之後,我們才是在下一行的最開始,繼續列印字元。

這裡引用一些便於理解的說明(阮一峰大佬部落格的評論):

attilax 說:

這個說法我有點兒補充::"回車"(carriage return)和"換行"(line feed) 是來源機械英文打字機的...電傳打字機那個是後來的...

"車"指的是紙車,帶著紙一起左右移動的模組。。。 當開始打第一個字之前,要把紙車拉到最右邊,上緊彈簧。。隨著打字, 彈簧把紙車拉回去..每當打完一行後,紙車就完全收回去了...所以叫回車.. 換行的概念就是 :: 打字機左邊有個"把手 ",往下 扳動一下,紙會上移一行..

繼承:計算機

後來,計算機發明瞭,這兩個概念也就被搬到了計算機上。在 ASCII 碼裡:

  • CR 用符號 \r​ 表示,十進位制 ASCII 程式碼是 13, 十六進位制程式碼為 0x0D;
  • LF 使用 \n​ 符號表示,ASCII 程式碼是 10, 十六製為 0x0A;

分歧:一個字元還是兩個字元

那時,儲存器很貴,一些科學家認為在每行結尾加兩個字元太浪費了,加一個就可以。於是,就出現了分歧。

  • Unix 系統裡,每行結尾只有 “LF”,即”\n​”
  • Windows 系統裡面,每行結尾是 “LFCR”,即 “\n\r​”
  • Mac 系統裡,每行結尾是 “CR”,即”\r​”

分歧的後果

在 Windows 下儲存的檔案,預設就是 CRLF 作為結尾的。

而在 Linux 下儲存的檔案,預設是以 LF 作為結尾的。

因此,Unix/Mac 系統下的檔案在 Windows 裡開啟的話,所有文字會變成一行;

而 Windows 裡的檔案在 Unix/Mac 下開啟的話,在每行的結尾可能會多出一個 ^M​ 符號。

這種換行符,還可能導致程式錯誤。例如,你在 Windows 下編寫了一個 shell 程式,其是以 CRLF 作為結尾;而如果你直接上傳到 Linux 下執行,Linux 會報錯,因為換行符不同。

在不同平臺間使用 FTP 軟體傳送檔案時

  • ascii 文字模式傳輸模式下,一些 FTP 客戶端程式會自動對換行格式進行轉換,經過這種傳輸的檔案位元組數可能會發生變化。

    git add .
    warning: LF will be replaced by CRLF in package-lock.json.
    The file will have its original line endings in your working directory
    
  • 如果你不想 ftp 修改原檔案,可以使用 bin 模式 (二進位制模式) 傳輸文字。

注:可以在 Linux 下用 dos2unix 命令和 unix2dos 命令,來轉換每行的結尾。

在 Windows 下,一般編輯器都支援換行符的轉換,以 VSCode 為例:

參考

本文主要參考了以下部落格,非常感謝他們:

回車和換行 - 阮一峰的網路日誌:參考並修改了下文字排版、新增了自己的說明

CR, LF, CR/LF 回車 換行 - Prayer - C++ 部落格

相關文章