在輸入文本時,回車鍵一敲,就開始了新的一行,這個習慣性用法難免誤導 C/C++ 的初學者們對 回車符(CR, Carriage Return)'\r' 和 換行符(LF, Linefeed)'\n' 的理解,這里這個問題我們暫且放下,后文再談。先讓我們來看看關於“回車”的有趣歷史來源。
關於“回車鍵”的來歷,要追朔到機械英文打字機的時代。在這種打字機上有個叫“字車”的部件,大概就是下面那個部分,會左右不停地跑的那東西。
當輸滿一行后,使用者就要把“字車”推到起始位置,這時打字機就會有兩個動作,一是“字車”歸位,二是滾筒上卷一行(相當於“字車”下移一行),這樣就可以開始輸入下一行了,這里推動“字車”的動作就稱為“回車”。
上述打字機的“字符”歸位的動作就相當於我們的 回車 '\r',只回到行首而仍在當前行,而滾筒上卷的動作就相當於 換行 '\n',移動到下一行。回車符 '\r' 對應 ASCII 碼的16進制是 0x0d,10進制是 13,換行符 '\n' 對應16進制是 0x0a, 10進制是 10。
而不同的系統對回車的處理是不同的:在我們常用的 Windows 系統中用 "\r\n"兩個字符來表示,如圖,在第一行與第二行之間有兩個字符位,分別是 0D 0A,即 ASCII 碼對應的 '\r'和'\n'。這樣的表示方法就和打字機的行為很相似了。
那么,同樣的方法,在 Linux 上會是什么情況呢?請繼續看。
在 Linux 上通過 vim 我們看到,在 a, ab, abc 之間只有一個字符位了,對應的是 0a,即 ASCII 碼中的 '\n',這就說明在 Linux 上只用了一個換行字符來表示。
那么接下來讓我們回到 C/C++ 中 '\r' 和 '\n' 的討論中吧。在 C/C++ 中原風原味地保留了對換行符的這種理解,回車符 '\r' 僅表示回到行首,並沒有包含換行的動作,換行是由 '\n' 來完成的,初學者一定要分清這兩個符號的意義。
這里再提一個與 '\r' '\n' 類似的一個轉義字符:退格(BS, Backspace)'\b',顧名思義,這個字符的意義是往前退一格,這里需要特別提醒的是:退格 '\b' 和回車 '\r' 都只是光標的移動,不會刪除前面的文本!
現在讓我們用一段簡單的代碼來驗證 '\r' '\n' '\b' 的作用效果。
C代碼:
1 #include <stdio.h> 2 3 int main(int argc, char const *argv[]) 4 { 5 printf("abc\r\ncba\rrr\bz\n"); 6 printf("abcd\b\b"); 7 getchar(); 8 9 return 0; 10 }
C++代碼:
#include <iostream> int main(int argc, char const *argv[]) { using namespace std; cout << "abc\r\ncba\rrr\bz\n"; cout << "abcd\b\b"; cin.get(); return 0; }
首先我們看下輸出的第一行 "abc\r\ncba\rrr\bz\n":
在輸出 abc 后 \r 使回車符回到當前行即第一行的行首,但不刪除字符,所以第一行最終顯示 abc,然后 \n 使光標移到下一行,接着輸出 cba,\r再次讓光標回到行首,這次不換行,直接接着輸出 rr,這樣達到的效果是行首兩個字符 cb 被替換為 rr,接着 \b 使光標向前一位,輸出 z,這樣第二個 r 就被換成了 z,然后換行,最終第二行顯示結果就是 rza。
接着為了更直觀地證明只有光標移動而不刪除字符,我們看看第二行代碼。"abcd\b\b",在兩個 \b 過后,光標向前移動到 c 的下面(或者是 c 上的方塊光標,亦或是在 c 前的 I 形光標),為了使光標停留以便觀察,我們添加了 getchar() 和 cin.get()。
所以程序運行后的結果將是:
abc rza abcd
同時可以看到光標停留在上述位置,當然,這時如果你再輸入字符,就會從光標的位置開始向后將 c 甚至 d 覆蓋。
最后,附上一張轉義字符的表格,供大家參考。
轉義字符
|
意義
|
ASCII碼值(十進制)
|
ASCII碼值(十六進制)
|
\a
|
響鈴(BEL)
|
007
|
0x07
|
\b
|
退格(BS) ,將當前位置移到前一列
|
008
|
0x08
|
\f
|
換頁(FF),將當前位置移到下頁開頭
|
012
|
0x0C
|
\n
|
換行(LF) ,將當前位置移到下一行開頭
|
010
|
0x0A
|
\r
|
回車(CR) ,將當前位置移到本行開頭
|
013
|
0x0D
|
\t
|
水平制表(HT) (跳到下一個TAB位置)
|
009
|
0x09
|
\v
|
垂直制表(VT)
|
011
|
0x0B
|
\\
|
代表一個反斜線字符''\'
|
092
|
0x5C
|
\'
|
代表一個單引號(撇號)字符
|
039
|
0x27
|
\"
|
代表一個雙引號字符
|
034
|
0x22
|
\? |
代表一個問號 |
063 |
0x3F |
\0
|
空字符(NULL)
|
000
|
0x00
|
\ddd
|
1到3位八進制數所代表的任意字符
|
三位八進制
|
|
\xhh
|
1到2位十六進制所代表的任意字符
|
二位十六進制
|
小提醒:不要把斜杠搞反咯。\轉\義\字\符