天天看点

回车和换行 \r \n(你想知道的C语言 1.7)

Q: 何为"回车", 何为"换行"?

A: 回车的英文是"Carriage Return", 换行为“New Line” or "Line Feed".

    回车的概念从计算机终端的角度不太容易理解, 回溯到早期电传打字机, 回车是为了把“打字”部件拉回当前行开始. 看过医院或者银行小型机械打印机,多行文本打字头会不断拉回到开头, 就可以理解成会发生多次回车.

    换行并不是"打字"部件移动到下一行,打字部件一般是硬件固定的,而是滚筒上卷一行, 看起来像是一行被吃掉了, 所以被叫做Line Feed.

    到计算机终端显示时代,回车的概念开始弱化, 换行 New Line更被大家所熟悉和理解.

Q: 为什么回车换行的表示形式有很多种, 比如\n, \r\n, \r?

A: 计算机的存储一开始是很昂贵的, 一些科学家认为每行结尾两个字符太浪费了,一个就足够。于是,分歧出现了.

      可以参考: https://blog.csdn.net/wanghuiqi2008/article/details/8069775

      比如Linux用'\n', Windows用"\r\n", Mac Classic用'\r'(Mac最新也用'\n').

      这就可以解释为什么在不同平台互相打开文本文件可能出现结尾乱码或者多行被合并的问题.

Q: 在使用的平台上实际验证使用的是'r'还是'\n'.

A: 可以通过dump文本文件的二进制形式来确认, 文件1如下.

回车和换行 \r \n(你想知道的C语言 1.7)

二进制形式如下:

回车和换行 \r \n(你想知道的C语言 1.7)

可以看到两行的间隔是'\n'.

Q: 回车'\r'在终端显示还有意义吗?

A: 是有的! 在某些会不断刷新同一行数据的情形, '\r'大有可为.

     如下,我们构造用\r覆盖开头数据的场景.

echo -en '1\r2\n3' > 123
           

      注: 参数“-e”为处理特殊字符.

    二进制:

回车和换行 \r \n(你想知道的C语言 1.7)

    文本显示:

回车和换行 \r \n(你想知道的C语言 1.7)

      最开始的1已经被后面的2覆盖了.

     不过一些文本编辑App可能会把'\r'和'\n'等同对待,毕竟显示文本不需要对'r'和'\n'细致区分.

回车和换行 \r \n(你想知道的C语言 1.7)

    如下是从0显示到9, 间隔是1秒,每次都会覆盖之前的显示,到9后重置为0.

    carriage.c: https://github.com/cxsjabc/basic/blob/dev/c/_topics/printf/carriage.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

void carriage()
{
	char c = '0';

	while(1) {
		printf("%c", c);
		fflush(stdout);

		++c;
		if (c > '9')
			c = '0';
		printf("\r");

		sleep(1);
	}
}

int main(int argc, char *argv[])
{
	carriage();
	return 0;
}
           

Q: 有没有自动转换'r', '\n'和"\r'n"的工具?

A: unix2dos和dos2unix工具可以实现'\n'和"\r\n"互转.

     主要就是替换字符, 有实现一版unix2dos, 代码位于: https://github.com/cxsjabc/basic/blob/dev/c/_topics/printf/unix2dos.c

作者:     陈曦
环境:     MacOS 10.14.5
         Apple LLVM version 10.0.1 (clang-1001.0.46.4)
         Target: x86_64-apple-darwin18.6.0
 
转载请注明出处