关于“回车”的有趣历史 及 “回车”与“换行”的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于“回车”的有趣历史 及 “回车”与“换行”的区别相关的知识,希望对你有一定的参考价值。

  在输入文本时,回车键一敲,就开始了新的一行,这个习惯性用法难免误导 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位十六进制所代表的任意字符
二位十六进制

  小提醒:不要把斜杠搞反咯。\转\义\字\符

以上是关于关于“回车”的有趣历史 及 “回车”与“换行”的区别的主要内容,如果未能解决你的问题,请参考以下文章

终于搞懂了回车与换行的区别---转

关于换行符CR和LF的区别

关于C语言中的换行符和回车符

关于MYSQL表记录字段换行符回车符处理

input placeholder可以换行吗

换行和回车野史