掰碎了講換行符和回車符

一開始對這個概念還只是有點模糊,不太在乎,結果一搜索才發現,這東西太有意思了,不只有個有趣的故事,並且自己也有不少門道,還勾起了一些以前的回憶,原來之前也跟這個問題打過交道啊。html

1基本概念python

 

 

 

控制字符linux

本義c++

換行符web

\n編程

newlinewindows

LF (Line Feed)編輯器

光標直接往下一行(不必定是行首)ide

回車符編碼

\r

return

CR(Carriage Return)

光標從新回到本行開頭

基本概念如上表所示。

2由來

爲何會有這兩個東西呢?它有一個有趣的傳說:在計算機尚未出現以前,有一種叫作電傳打字機(Teletype Model 33)的玩意,每秒鐘能夠打10個字符。可是它有一個問題,就是打完一行換行的時候,要用去0.2秒,正好能夠打兩個字符。要是在這0.2秒裏面,又有新的字符傳過來,那麼這個字符將丟失。

因而,研製人員想了個辦法解決這個問題,就是在每行後面加兩個表示結束的字符。一個叫作「回車」,告訴打字機把打印頭定位在左邊界;另外一個叫作「換行」,告訴打字機把紙向下移一行。

這個分秒級的傳說沒有考證,可是確實,看名字也能知道換行符確實是用來將打字紙滾動一行,回車符是用來將打印頭移到行開頭也就是左邊界。如當前位置是第5行第6個字符,那麼回車是當前位置變成第5行第1個字符,而換行是當前位置變成第6行第6個字符位置,這樣在打字機上打印時,只要回車而不換行,就能夠在同一行上重複打印字符。

3如今狀況

後來,計算機發明瞭,這兩個概念也就被般到了計算機上。那時,存儲器很貴,一些科學家認爲在每行結尾加兩個字符太浪費了,加一個就能夠。因而,就出現了分歧:

\n:  UNIX系統/MAC OS X系統行末結束符

\r:   MAC OS系統行末結束符

\n\r: windows系統行末結束符

也就是說在計算機上,其實只須要一個符號表示這行已經結束,光標移向下一行行首。大部分系統採用了直接使用換行符\n也就是紙滾轉一行的方式,只有windows以爲按照傳統來,用兩個符號表示光標移向下一行行首比較穩當。

而ENTER鍵的定義是直接配合操做系統的,若是是UNIX就單是\n,windows就是\n\r,總之實現一個換行功能。另外,其實這裏說的換行符跟word中的段落標記^p是同樣的。

4問題來了

誒,這裏問題就來了,既然UNIX系統中\n徹底表示換行回車,那麼其中\r表示什麼呢?這個我並不關心。

另外既然windows系統\n\r表示換行回車,那麼單獨的\n和\r就仍是本來的意思即換行和回車麼?

這個問題咱們就能夠探究一下了。

如何探究,其實這也有個問題,以前沒有想到,後來出問題了查了半天才明白。

由於我若是在windows系統中的txt文檔中直接寫\n,它會被當成兩個字符讀取的,並無轉義的功能,因此我準備的探究方式是經過程序向文檔寫入字符,這個寫入的字符中沒有天然換行回車,全部換行回車都是顯性表示,這樣咱們把其餘字符和單獨的\n和\r和\n\r寫入windows系統中的txt文檔,就能夠觀察到windows系統中單獨的\n和\r各表示什麼。

接下來我我進行了實驗,並對着實驗結果陷入了深深思考,終於發覺了哪兒有問題。

這個設想的探索方案看起來很清晰可行,可是其實它創建在咱們的一個假設上:當咱們經過程序向文檔寫入字符時,咱們認爲程序會原本來本地把咱們寫入的字符串 ’這是第一行\n\r這是第二行\n這是長一些的第三行\r這是第四行’ 先用GBK編碼成01碼,而後把這段01碼寫入文本文檔,而後當咱們打開文本文檔的時候,文本文檔把這段01碼用GBK解碼並顯示出來。

5實驗結果和分析

但實驗結果告訴咱們可能並非這樣,由於個人實驗結果是這樣的:

1)對於\r,win7.txt不識別(就當沒有同樣)

2)對於\n,win7.txt識別,執行結果是:換行回車

3)對於\n\r(和\r\n),win7.txt識別,執行結果是:換行回車(很容易理解,當\r不存在直接實現\n)

這個跟設想的好像不同,後來找到了一個可能的解釋:在Windows環境中,若是輸入到文本文件,在編碼時,程序中的一個'\n'換行符被解釋成'\r'、'\n'兩個字符;相反,若是讀取文本文件,文件中的相鄰的兩個'\r'、'\n'會合併爲一個'\n'輸出(這是發生在轉碼的時候嗎)。

而此時我順便用程序傳輸法作實驗看了下對於python控制檯輸出和wxpython的文本框窗口,都是如何識別程序傳送的'\r'、'\n'和’ \n\r’的。必須聲明,包括上面的結果,這樣子的狀況都是通過程序潤色的,第6節會有一些真實狀況的參考。

5.2  python控制檯輸出

1)對於\r,識別,執行結果是:把光標移到當前這行的行首,若是接下來是字符,會同時刪去這行全部字符,開始顯示接下來的字符,若是接下來是\n,這行文字不會被刪掉,光標到下一行行首(也就是說\r後面的字符會直接覆蓋上一行字符,也就是上一個\n以前的字符)

2)對於\n,識別,執行結果是:換行回車

3)對於\n\r,識別,執行結果是:換行回車(很容易理解,當\n執行時,光標換行回車,再執行\r後,什麼事情其實都沒有作)

4)對於\r\n,識別,執行結果是:換行回車,就是上面提到\r接下來是\n的狀況,不刪字符而後換行

5.3  wxpython的文本框窗口(單行文本框)

1)對於\r,識別,執行結果是:出現一個看不到的空格,並且光標停在這個空格後面,能夠往前刪除掉它

2)對於\n,識別,執行結果是:出現一個看不到的空格,並且光標停在這個空格後面,能夠往前刪除掉它

3)對於\n\r(和\r\n),識別,執行結果是:出現兩個看不到的空格,並且光標停在這兩個空格後面,能夠往前刪除掉它

5.4  wxpython的文本框窗口(多行文本框)

1)對於\r,識別,執行結果是:換行回車

2)對於\n,識別,執行結果是:換行回車

3)對於\n\r,識別,執行結果是:兩個換行回車

4)對於\r\n,識別,執行結果是:1個換行回車(這個有點怪。。)

6真實狀況

0)在Windows中:

'\r'  回車,回到當前行的行首,而不會換到下一行;

'\n'  換行,換到當前位置的下一行,而不會回到行首;

1)Unix/Mac系統下的文件在Windows裏打開,全部文字會變成一行

2)Windows裏的文件在Unix/Mac下打開,在每行的結尾可能會多出一個^M符號

3)Linux保存的文件在windows上用記事本看的話會出現黑點

4)在linux下,命令unix2dos 是把linux文件格式轉換成windows文件格式,命令dos2unix 是把windows格式轉換成linux文件格式。

5)在不一樣平臺間使用FTP軟件傳送文件時, 在ascii文本模式傳輸模式下, 一些FTP客戶端程序會自動對換行格式進行轉換. 通過這種傳輸的文件字節數可能會發生變化。 若是你不想ftp修改原文件, 可使用bin模式(二進制模式)傳輸文本。

6)一個程序在windows上運行就生成CR+LF換行格式的文本文件,而在Linux上運行就生成LF格式換行的文本文件。

7其餘

1

在C語言裏回車和換行是兩個概念,回車是指光標由行中任意位置移動到行首,換行指換到下一行的狀況。
第二個以及之後的多個(個數不定)的參數:後面的參數是用來告訴計算機在前面的%d佔位符上將輸出值得變量名。
咱們作一個試驗:printf("hello") ;
輸出結果:helloPress any key to continue ...
你們會看到,這時沒有了回車換行,Press any key to continue ...就跑到上一行了。
對於回車的格式有單獨的格式符\r
例如:printf("abcde\rf\n");他的輸出就爲:
fbcde
press any key to continue ...
實際上,計算機先輸出:
abcde_      (注意「_」表明光標的位置)
而後,遇到\r格式符:
abcde       (注意此時,光標在字母a的下方)
在而後,輸出f和\n(回車換行)
fbcde       (注意此時字母f把字母a覆蓋掉了)
_           (這時,光標在下一行的行首)
緊跟着,Vc++集成環境輸出Press any key to continue ...字符串。

2)軟硬回車

硬回車就是普通咱們按回車產生的,它在換行的同時也起着段落分隔的做用。 
軟回車是用 Shift + Enter 產生的(在word中看到這個樣子↓,在替換中名字叫手動換行符^l),它換行,可是並不換段,即先後兩段文字在 Word 中屬於同一「段」。在應用格式時你會體會到這一點。 
咱們經常使用的回車是硬回車,就是在word中敲擊Enter鍵產生的那個彎曲的小箭頭,佔兩個字節。這種回車能夠有效地把段落標記出來分清楚。在兩個硬回車之間的文字自成一個段落,能夠對它單獨設置段落標記而不用擔憂其餘段落受到影響。這也是咱們習慣用硬回車的緣由:排版方便。 
可是硬回車也給咱們帶來了麻煩。你若是是網頁設計者,或者是論壇遊俠,必定有這樣的經歷:當你打算換行時,換出的行卻實在不能恭維,行間距太大了!其實這和硬回車的原理是同樣的,只不過在word等文本編輯器中沒有顯示出它的「原本面目」。不過這樣的排版的確形成了不小的困難,這時咱們就得請出硬回車的兄弟:軟回車。 
軟回車只佔一個字節,在word中是一個向下的箭頭。若是你從很複雜的網頁中向word中複製過文字的話,對它必定不會陌生。可是想在word中直接輸入軟回車可不是那麼容易的。由於軟回車不是真正的段落標記,它只是另起了一行,不是分段。因此它不是很利於文字排版,由於它沒法做爲單獨的一段被賦予特殊的格式。可是儘管如此,它在網頁設計中仍是具備舉足輕重的地位的。 
軟回車能使先後兩行的行間距大幅度縮小,由於它不是段落標記,要和法定的段落標記——硬回車區別出來。硬回車的html代碼是<p>..</p>,段落的內容就夾在裏面,而軟回車的代碼很精悍:<br>。所以在網頁中想用到軟回車,只需切換到代碼頁面,鍵入軟回車的代碼便可。 
下面我講一下不一樣編輯器文字互相拷貝時回車的轉化狀況。 
地球人都知道的,網頁的文字若是複製到word中,則硬回車變爲彎曲的箭頭,軟回車變爲向下的箭頭。結果形成習慣用word編輯文本的朋友很不習慣很不舒服的狀況。 
word中的文本複製到網頁中也是一樣的道理。能夠說word和網頁比較兼容的,要不怎麼會有「保存爲web頁」這種選項呢? 
記事本也是你們摸的比較多的編輯器。可是近年來隨着社會發展外加記事本的種種弊端,許多人都將其打入冷宮。對此我只能表示遺憾,由於記事本自己的功能不豐富就是別的編輯器所取代不了的優勢。你們再次將網頁的文字複製時,不妨粘貼到記事本里試試。哈哈,無論網頁設計者用的是什麼回車,如今都變成一種回車了!怎麼,你不信?那就看看吧:軟回車變成了普通的回車,硬回車變成了兩個普通的回車。你再從記事本里複製文字到word,記事本里的回車無一例外全都變成了硬回車!你再再從記事本里複製文字到網頁編輯器,全部回車就都變成軟回車了!! 

3)再談文件操做時對換行回車的處理

在編程時文件操做  wb(二進制方式)或者wt(文本方式)也會有影響。我作了個實驗(實驗用.net2003)  在01.txt文件中輸入12而後enter,在ultraedit中看到的二進制是31 32 0d 0a  而後程序以下:  int mian()  { FILE *fp1,*fp2,*fp3,*fp4,*fp5,*fp6;  char a[10];  char b[10];  fp1 = fopen("01.txt","r");  fp3 = fopen("02.txt","w");  fread(a,sizeof(unsigned char),8,fp1); //a裏是31 32 0a  fwrite(a,sizeof(unsigned char),8,fp3); //02.txt裏是31 32 0d 0a ,緣由是輸入的狀況下,換行回車轉換成換行,而後輸出時換行又會轉成換行回車  fclose(fp1);  fclose(fp3);  fp2 = fopen("01.txt","rb");  fp4 = fopen("03.txt","wb");  fread(b,sizeof(unsigned char),8,fp2); //b裏是31 32 0d 0a  fwrite(b,sizeof(unsigned char),8,fp4); //03.txt裏是31 32 0d 0a ,緣由是二進制狀況下回車和換行的(相似文本方式的那種轉換)是不存在的  fclose(fp2);  fclose(fp4);  return 0;  }  好像結論是這樣的:讀的方式下,在文本方式下,enter是0x0a;在二進制方式下,enter是0x0d,0x0a。  MSDN中查到這樣的話:Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. (輸入的狀況下,換行回車轉換成換行,而後輸出時換行又會轉成換行回車)When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters. For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters.  Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed. (二進制狀況下回車和換行的轉換是不存在的). 

相關文章
相關標籤/搜索