it-swarm.cn

'\ n'和'\ r \ n'之间的区别

是的,我知道'\n'在UNIX中写换行符,而对于Windows,则有两个字符序列:'\r\n'。从理论上讲,这一切都很好,但是我的问题是为什么?为什么在Windows中回车符是多余的?如果UNIX可以在\n为什么Windows需要两个字符来完成此操作?

我正在阅读David Beazley的Python书,他说:

例如,在Windows上,写入字符'\ n'实际上会输出两个字符的序列'\ r\n'(并且在回读文件时,'\ r\n'被转换回单个'\ n'字符)。

为什么要付出额外的努力?

我会说实话。我很早就知道它们之间的区别,但是从来没有问过为什么。我希望今天能回答。

谢谢你的时间。

108
sukhbir

向后兼容。

Windows与MS-DOS向后兼容(因此,即使如此也是如此),并且MS-DOS使用CR-LF约定,因为MS-DOS与使用CR-LF约定的CP/M-80(有点偶然)兼容。是您驾驶打印机的方式(因为打印机最初是计算机控制的打字机)。

打印机有一个单独的命令可将纸张向上移动一行到新行,还有一个单独的命令可将笔架(安装纸张的位置)返回左边缘。

这就是为什么。而且,是的,这很麻烦,但这是一揽子交易的一部分,该交易使MS-DOS可以胜过CP/M,Windows 95可以胜过DOS之上的所有其他GUI,而Windows XP从Windows 98接管。

(注意:现代激光打印机仍然具有这些命令,因为它们也与较早的打印机向后兼容-特别是HP做得很好)

对于那些不熟悉打字机的人,以下视频显示了打字的方式: http://www.youtube.com/watch?v=LJvGiU_UyEQ 。请注意,即使纸张移动很简单,也要先将其向上移动,然后再将其退回。丁通知打字员结束将至,并为此做准备。

133
user1249

据我所知,这可以追溯到打字机的时代。

\r是回车符,即您在页面上输入的位置向左移动(如果这是您的文化,则向右移动)

\n是新行,它将使您的纸张向上移动一行。

在打字机上仅执行其中一项操作会把您放在错误的位置,开始写新的一行文本。

当计算机问世时,我猜有些人保留了旧模型,但是其他人意识到这是不必要的,因此将完整的换行符封装为一个字符。

21
Matt Ellen

我不知道这是否是常识,但是应该指出,现代终端仿真器仍然可以理解CR:

$ printf "hey world\rsup\n"
sup world

对于进度指示器,例如.

for i in {1..100}
do
    printf "\rLoading... %d%%" $i
    sleep 0.01
done
echo
9
Daniel Lubarov

从历史上看,换行意味着压板(您在其上输入的滚轮)旋转了一行,从而导致文本显示在下一行中,但出现在下一列中。

回车的意思是“将您输入的位返回到行首”。

Windows使用CR + LF是因为MS-DOS这样做了,因为CP/M这样做了,因为它对于串行线有意义。

Unix复制了\ n约定,因为Multics这么做了。

我怀疑如果您深入挖掘,您会发现实施者之间存在政治分歧!

(您省去了额外的乐趣,在Mac约定中(或曾经是Mac约定)仅使用CR来分隔行。现在Unicode也具有自己的行分隔符U + 2028!)

7
Frank Shearar

换行符的历史 (维基百科):

ASCII由ISO和ASA(ANSI的前身组织)同时开发。在1963年至1968年期间,ISO草案标准支持单独使用CR + LF或LF作为换行符,而ASA草案仅支持CR + LF。

CR + LF序列在许多采用电传打字机(通常为ASR33)作为控制台设备的早期计算机系统中普遍使用,因为需要此序列将这些打印机放置在新生产线的开头。在这些系统上,通常会常规编写文本以使其与这些打印机兼容,因为尚未很好地开发出将设备的硬件详细信息隐藏在应用程序中的设备驱动程序的概念。应用程序必须直接与电传打字机对话并遵循其约定。

这两个功能的分离掩盖了以下事实:打印头无法在一个字符的时间内从最右端返回到下一行的开头。这就是为什么总是先将CR与序列一起发送的原因。实际上,通常有必要发送额外的字符(外部CR或NUL,将被忽略)以使打印头有时间移到左边距。

即使电传打字机被具有更高波特率的计算机终端所取代,许多操作系统仍支持自动发送这些填充字符,以与需要多个字符时间才能滚动显示的廉价终端兼容。

MS-DOS(1981)采用了CP/M的CR + LF; CP/M使用CR + LF对于通过串行线使用计算机终端很有意义。此约定由Microsoft的更高版本的Windows操作系统继承。

Multics操作系统于1964年开始开发,仅使用LF作为其换行符。Unix遵循Multics的惯例,后来的系统遵循Unix。

6
Craige

人们问“为什么Unix为什么可以\n而不是Windows”是什么意思?这是一个奇怪的问题。

  1. 该操作系统几乎与它无关。应用,库,协议和文件格式如何处理问题更多。除了操作系统读取/写入基于文本的配置或命令行命令的位置以外,对操作系统进行故障都没有意义。
  2. 大多数Windows应用都可以读取\n\r\n都很好。他们还输出\r\n,让每个人都很高兴。程序不能简单地“做” \n\r\n-它接受一个,另一个或两者和输出一个,另一个或两者。
  3. 作为程序员,这实际上几乎应该从不困扰您。实际上,每种语言/平台都具有编写正确的终端行和最可靠地阅读的功能。我唯一需要解决的问题是当我编写 HTTP服务器 -时,这是因为某个浏览器(提示:IE之后的第二个最受欢迎的浏览器)正在执行\n而不是 正确\r\n
  4. 一个更相关的问题是,为什么这么多现代Unix应用程序仅在知道某些协议和程序不喜欢的情况下仅输出\n
5
Rei Miyasaka

约定在其各种系统上(在unix类型的系统上为\ n,在Windows上为\ r\n等)保留的原因是,一旦选择了约定,就无法在不破坏人们文件的情况下对其进行更改。而这通常被皱眉。

Unix类型的系统是在很早的时候就使用各种电传打字机模型开发的,在某个时候,有人决定设备在换行时应该回车。

Windows来自DOS,因此对于Windows,问题实际上是:为什么DOS使用此cr/lf序列?我猜想它与CP/M有关,因为DOS是CP/M的根源。同样,电传打字机的特定模型可能起到了作用。

4
Michael Kohne

这是最佳来源-Microsoft的答案。 为什么行终止符为CR + LF?

该协议可以追溯到电传打字机的时代。 CR代表“回车”-CR控制字符将打印头(“回车”)返回到第0列而不前进纸。 LF代表“换行”-LF控制字符将纸张前进一行而不移动打印头。因此,如果要将打印头返回到零列(准备打印下一行)并进纸(以便在新纸上打印),则需要CR和LF。

如果转到各种Internet协议文档,例如RFC 0821(SMTP),RFC 1939(POP),RFC 2060(IMAP)或RFC 2616(HTTP),您会发现它们都将CR + LF指定为线路终止顺序。因此,真正的问题不是“为什么CP/M,MS-DOS和Win32使用CR + LF作为行终止符?”而是“为什么其他人选择不同于这些标准文档并使用其他行终止符?”

Unix采用普通LF作为行终止顺序。如果查看stty选项,您会发现onlcr选项指定是否应将LF更改为CR + LF。如果此设置错误,则会显示阶梯文本,其中

each
    line
        begins

上一行停止的地方。因此,即使unix处于原始模式,也需要CR + LF终止行。 LF)之前的隐式CR是unix发明,可能很经济,因为它每行节省一个字节。

C语言的统一祖先将此约定引入了C语言标准,该标准只需要“\n”(对LF进行编码)即可终止行,这给运行时库带来了负担,可以将原始文件数据转换为逻辑行。

C语言还引入了术语“换行符”来表达“通用行终止符”的概念。有人告诉我ASCII委员会在1996年左右将字符0x0A的名称更改为“换行符”,因此混乱程度进一步提高了。

2
Ondra Žižka