1. 程式人生 > >換行符‘\n’和回車符‘\r’

換行符‘\n’和回車符‘\r’

http://hi.baidu.com/jsj09/blog/item/860fa6fb376e4c9f9e5146a7.html

在計算機還沒有出現之前,有一種叫做電傳打字機(Teletype Model 33)的玩意,每秒鐘可以打10個字元。但是它有一個問題,就是打完一行換行的時候,要用去0.2秒,正好可以打兩個字元。要是在這0.2秒裡面,又有新的字元傳過來,那麼這個字元將丟失。

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

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

後來,計算機發明瞭,這兩個概念也就被般到了計算機上。那時,儲存器很貴,一些科學家認為在每行結尾加兩個字元太浪費了,加一個就可以。於是,就出現了分歧。

Unix系統裡,每行結尾只有“<換行>”,即“\n”;Windows系統裡面,每行結尾是“<換行><回車>”,即“\n\r”;Mac系統裡,每行結尾是“<回車>”。一個直接後果是,Unix/Mac系統下的檔案在Windows裡開啟的話,所有文字會變成一行;而Windows裡的檔案在Unix/Mac下開啟的話,在每行的結尾可能會多出一個^M符號。


在ascii中,回車和換行是不同的字元。0x0A是回車,即游標移動到本行的最左面;   0x0D是換行,即游標移動到下一行。   
    
  在dos視窗中按回車鍵,其實是輸入了兩個字元0x0A,0x0D,對應到c中,就是\r(回車)\n(換行)

在C語言中   
將  \n   存入檔案   
  window:   0d   0a   
  unix:   0d   
  如果不存到檔案中,不會變。   
  如果從檔案中提取,   
  windows:   0d   0a   ->   \n   
  unix   :   0d   ->   \n

[  遊客   發表於  2008-03-27 18:55  ]

回車鍵,即鍵盤上的ENTER鍵,是一個比較有用的鍵,在文字編輯時,回車鍵的作用是換行,在輸入網址時回車鍵的作用是“轉到”,在執行DOS命令時,回車鍵的作用是執行……
    在標準鍵盤上,回車鍵一共有2個,一個在主鍵盤區的右邊,Shift鍵的上面,一個在小鍵盤的右下角,加號鍵的下面。

回車鍵的歷史

    關於“回車鍵”的來歷,還得從機械的英文打字機說起。在打字機上,有一個部件叫“字車”,每輸入一個單詞,“字車”就前進一格。當輸滿一行後,使用者就要推動“字車”到起始位置,這時打字機會有兩個動作:“字車”歸位、滾筒上卷一行(相當於“字車”下移一行),以便開始輸入下一行,這中推動“字車”的動作叫“回車”。後來,在電動的打字機上,人們增加了一個直接起“回車”作用的鍵。他被稱為“回車鍵”。 
  在現今的電腦鍵盤上,“回車鍵”上曾使用過“CR”、“RETURN”的字樣,後來才統一確定為“Enter”。

回車的ASCII程式碼

    16進位制是“0x0d”
    10進位制是“13”
    在某些語言中可以用‘\r’表示。

[  遊客   發表於  2008-03-27 18:59  ]

如果用過機械打字機,就知道回車和換行的區別了。。。
  換行就是把滾筒卷一格,不改變水平位置。   
  回車就是把水平位置復位,不捲動滾筒。


但是我們平時按得Enter到底是回車還是換行,不太清楚??
看到一種說法:windows下enter是 \n\r,unix下是\n,mac下是\r

在MS的系統中純文字格式按一個回車鍵是輸入了兩個字元,一個回車一個換行。在LINUX系統中則只是一個回車。
//以上內容參考了http://topic.csdn.net/t/20040617/23/3101951.html#和http://topic.csdn.net/t/20021113/09/1171659.html的討論  

還有在程式設計時檔案操作

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. (二進位制情況下回車和換行的轉換是不存在的).

再引用一篇:http://zhidao.baidu.com/question/27868102.html?fr=qrl3

軟硬回車 }

硬回車就是普通我們按回車產生的,它在換行的同時也起著段落分隔的作用。 
軟回車是用 Shift + Enter 產生的,它換行,但是並不換段,即前後兩段文字在 Word 中屬於同一“段”。在應用格式時你會體會到這一點。 


切換: 

編輯——替換,點選高階,在“查詢內容”點入“特殊字元”中的手動換行符,再在“替換為”中點入“特殊字元”中的段落標記,最後點選全部替換。 




鍵盤上只有一種回車鍵Enter,但卻有兩種不同性質的換行標記,不能不說是一個奇蹟。 

我們常用的回車是硬回車,就是在word中敲擊Enter鍵產生的那個彎曲的小箭頭,佔兩個位元組。這種回車可以有效地把段落標記出來分清楚。在兩個硬回車之間的文字自成一個段落,可以對它單獨設定段落標記而不用擔心其他段落受到影響。這也是我們習慣用硬回車的原因:排版方便。 

但是硬回車也給我們帶來了麻煩。你如果是網頁設計者,或者是論壇遊俠,一定有這樣的經歷:當你打算換行時,換出的行卻實在不能恭維,行間距太大了!其實這和硬回車的原理是一樣的,只不過在word等文字編輯器中沒有顯示出它的“本來面目”。不過這樣的排版的確造成了不小的困難,這時我們就得請出硬回車的兄弟:軟回車。 

軟回車只佔一個位元組,在word中是一個向下的箭頭。如果你從很複雜的網頁中向word中複製過文字的話,對它一定不會陌生。但是想在word中直接輸入軟回車可不是那麼容易的。因為軟回車不是真正的段落標記,它只是另起了一行,不是分段。所以它不是很利於文字排版,因為它無法作為單獨的一段被賦予特殊的格式。但是儘管如此,它在網頁設計中還是具有舉足輕重的地位的。 

軟回車能使前後兩行的行間距大幅度縮小,因為它不是段落標記,要和法定的段落標記——硬回車區別出來。硬回車的html程式碼是<p>..</p>,段落的內容就夾在裡面,而軟回車的程式碼很精悍:<br>。因此在網頁中想用到軟回車,只需切換到程式碼頁面,鍵入軟回車的程式碼即可。 
下面我講一下不同編輯器文字互相拷貝時回車的轉化情況。 

地球人都知道的,網頁的文字如果複製到word中,則硬回車變為彎曲的箭頭,軟回車變為向下的箭頭。結果造成習慣用word編輯文字的朋友很不習慣很不舒服的情況。 

word中的文字複製到網頁中也是同樣的道理。可以說word和網頁比較相容的,要不怎麼會有“儲存為web頁”這種選項呢? 

記事本也是大家摸的比較多的編輯器。但是近年來隨著社會發展外加記事本的種種弊端,許多人都將其打入冷宮。對此我只能表示遺憾,因為記事本本身的功能不豐富就是別的編輯器所取代不了的優點。大家再次將網頁的文字複製時,不妨貼上到記事本里試試。哈哈,不管網頁設計者用的是什麼回車,現在都變成一種回車了!怎麼,你不信?那就看看吧:軟回車變成了普通的回車,硬回車變成了兩個普通的回車。你再從記事本里複製文字到word,記事本里的回車無一例外全都變成了硬回車!你再再從記事本里複製文字到網頁編輯器,所有回車就都變成軟回車了!!

[  遊客   發表於  2008-03-27 19:00  ]

\n是換行,英文是linefeed,ASCII碼是0xA。
\r是回車,英文是carriage return ,ASCII碼是0xD。

---------------------------------------------------------------------------------------------------------------------------

回車的傳說---兼談\n\r區別(轉載)

IT文摘2010-08-31 11:40:24閱讀86評論0  字號:訂閱

如果你有在windows下程式設計的經驗就會發現windows下敲下回車鍵會產生兩個字元CR和LF,用16進位制編輯器開啟windows下的文字檔案也會看到換行是0D和0A表示的,也就是CR和LF的ASCII編碼。而在UNIX類系統中換行只有一個字元LF,所以UNIX中的文字檔案在windows中用記事本開啟會出現不可解析字元且丟失換行格式,所有字元連成一行。
    因為windows下的記事本讀到LF時不知道這就是換行(只有CR和LF連續出現才能解釋為換行),於是當作不可列印字元處理,就是一個黑色方框。CR和LF分別表示“回車”(carriage return)和“換行”(line feed),ASCII編碼為13和10,在C語言中用\r和\n表示。
    為什麼windows下要用兩個字元表示換行?這就是今天要講的故事:《回車的傳說》
    在計算機剛剛誕生之時,廣泛使用Teletype公司製造的一種古老的終端(console terminal)電傳打字機ASR33。ASR33每秒鐘可以打10個字元。但是它有一個問題,就是打完一行換行的時候,列印頭從行尾移到行首再下移一行要用去0.2秒,正好可以打兩個字元。要是在這0.2秒裡面,又有新的字元傳過來,那麼這個字元將丟失,那時可沒有緩衝區暫存。Teletype的研究人員想了個辦法解決這個問題,就是在每行後面加兩個表示結束的字元。一個叫做“回車”,告訴打字機把列印頭定位在左邊界;另一個叫做“換行”,告訴打字機把紙向下移一行。這就是“換行”和“回車”的來歷,從它們的英語名字上也可以看出一二。
( 1968年蓋茨在湖濱中學玩的就是這種機器,他們通過這種終端編寫BASIC程式。因為 ASR 33只使用大寫字母,所以BASIC程式以大寫字母為主)
    後來,計算機的史前時代結束了,小型機誕生了,現代文明的鍵盤也發明了,但回車和換行的概念仍被保留下來。一些計算機設計者認為在每行結尾加兩個字元太浪費也沒有必要了,加一個就可以。於是就出現了分歧。
    Unix系統裡使用<line feed>表示換行,每行結尾只有一個換行符\n,MSDOS和Windows系統裡面每行結尾是<回車><換行>(<carriage return><line feed>)即\r\n,Apple的Mac系統裡每行結尾是<回車>(<carriage return>)即\r。一個直接後果是,Unix/Mac系統下的檔案在Windows裡開啟的話,所有文字會變成一行;而Windows裡的檔案在Unix/Mac下開啟的話,某些文字編輯器可能在每行的結尾會多出一個^M符號。
   本人覺得用兩個字元表示換行實在有些畫蛇添足,但是在網路的世界裡這一現象卻大量存在,不少網路協議規定報文必須使用CR-LF換行模式。
你怎麼看呢?前不久在CU的論壇對這一問題進行了討論:http://bbs2.chinaunix.net/thread-1067432-1-1.html
這個和程式設計有關係嗎?
有的,但是在標準C裡通常情況下是體會不到的,標準C的流提供系統無關抽象層。
可以在windows系統中進行一下實驗:
   
程式一:
----------------------------------------------
#include <stdio.h>
int main(void)
{
        int i;
        FILE *fp;
        if((fp=fopen("test.txt","w")) == NULL)    
        {
                fprintf(stderr,"open file error\n");
                return 1;
        }
    
        for(i=0;i<100;i++)
                fprintf(fp,"test\n");
        
        fclose(fp);
    
        return 0;
}
程式二:
-------------------------------------------------------------------------------------
#include <stdio.h>
int main(void)
{
        int i;
        FILE *fp;
        if((fp=fopen("test.bin","wb")) == NULL)    
        {
                fprintf(stderr,"open file error\n");
                return 1;
        }
    
        for(i=0;i<100;i++)
                fprintf(fp,"test\n");
        
        fclose(fp);
    
        return 0;
}
--------------------------------------------------------------------------------------
程式一輸出檔案大小是600位元組,程式二輸出檔案大小是500位元組,用記事本開啟程式一的輸出沒有什麼問題,每行一個test,開啟程式二的輸出發現所有的test連成一行,test之間是一個黑色方框符號分隔。用UltraEdit-32以16進位制編輯模式開啟test.bin可以檢視到黑色方框符號就是0A也就是\n,開啟test.txt則會發現換行是\r\n,這就是兩個檔案大小相差100位元組的原因。Unix類系統使用者開啟windows中的檔案就會遇到這種苦惱。
為什麼會有這種區別呢?
    畢竟是源自Unix系統,C語言中使用\n表示換行,而在實際的檔案中換行符號需要同作業系統一致,所以當我們在C中使用fopen開啟一個文字檔案時流實現了實際換行符與C中\n之間的轉換。在windows中當我們用fopen開啟文字檔案,然後從中讀到\r\n時流會轉換為\n,而當我們往檔案中寫入\n時流會轉換為\r\n。程式一是開啟文字檔案,程式二開啟的是二進位制檔案,因為流只對文字檔案進行換行表示的轉換,以二進位制模式開啟流不會做任何處理。所以當你以二進位制模式開啟一個文字檔案時將產生錯亂,你必須親自將\r\n解釋為\n,同樣的問題也會出現在以文字模式開啟二進位制檔案的情況.這也解釋了為什麼Unix類系統中的檔案不區分文字檔案和二進位制檔案的原因。
 
當我們使用標準輸入輸出函式時有這種情況嗎? 
再回到我們熟悉的標準輸入輸出stdin,stdout
    C的控制檯程式在載入進記憶體成為程序執行前C執行時庫自動開啟三個裝置並關聯到三個流:標準輸入流stdin,標準輸出流stdout,標準出錯流stderr
    通常在通用計算機中,沒有重定向前這三個流對應的裝置是:鍵盤,顯示器,顯示器。這三個都是字元裝置,所以是以文字檔案的模式開啟的,在windows下當我們在鍵盤上敲入回車鍵時產生字元\r\n,但是在OS核心把鍵盤驅動中讀到的字元傳送給流的緩衝區時流會將之轉換為\n,當我們向控制檯輸出\n時流將之轉換為\r\n再傳遞至核心,當我們繞過標準輸入輸出直接呼叫windows中coredll.lib進行控制檯輸入輸出時就必須面對這一現實,程式設計師負責實現這一轉換。 不同計算機上c語言統一規定為:
文字檔案的行結束符一律變成一個符號LF,也就是換行符,也就是new line符, 也就是'\n'.
“回車和換行符轉換成一個換行符”-- 對PC機而言,文字檔案行結束符,CRLF讀入後,丟掉CR,留   LF.
例如fgets() 讀入一行,行尾只有LF,沒有CR.