在输入文本时,回车键一敲,就开始了新的一行,这个习惯性用法难免误导 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 上只用了一个换行字符来表示,事实上,包括 Mac OS 在内的 Unix 系统也是这样的。
那么接下来让我们回到 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位十六进制所代表的任意字符
|
二位十六进制
|
小提醒:不要把斜杠搞反咯。\转\义\字\符