\ r和\ n有什么区别?
如何\r
和\n
不同? 我认为这与Unix与Windows和Mac有关,但我不确定它们究竟有什么不同,以及在正则expression式中search/匹配的内容。
他们是不同的人物。 \r
是回车符, \n
是换行符。
在“旧”打印机上, \r
将打印头送回到行首,然后\n
将纸张抬高一行。 因此,两者都需要在下一行开始打印。
显然现在有点不相关,尽pipe取决于控制台,您仍然可以使用\r
移动到行首并覆盖现有的文本。
更重要的是,Unix倾向于使用\n
作为行分隔符; Windows倾向于使用\r\n
作为行分隔符,而Mac(最多可以使用OS 9)将\r
用作行分隔符。 (Mac OS X是Unix-y,所以使用\n
;但是可能会有一些兼容情况,尽pipe使用了\r
。)
欲了解更多信息,请参阅维基百科新文章 。
编辑:这是语言敏感的。 例如,在C#和Java中, \n
总是表示Unicode U + 000A,它被定义为换行符。 在C和C ++中,水有点混乱,因为意义是平台特定的。 详情请参阅评论。
在C和C ++中, \n
是一个概念, \r
是一个字符, \r\n
(几乎总是)是一个可移植性错误。
想想一个旧的电传打字机。 打印头位于某一行和某列中。 当您将可打印的字符发送到电传打字机时,它会在当前位置打印字符,并将头部移动到下一列。 (除了打字机通常相对于打印头移动纸张之外,这在概念上与打字机相同。)
当你想完成当前行并开始下一行时,你必须做两个单独的步骤:
- 然后将打印头移回到行首
- 把它移到下一行。
ASCII将这些操作编码为两个不同的控制字符:
-
\x0D
(CR)将打印头移回到行首。 (Unicode将其编码为U+000D CARRIAGE RETURN
。) -
\x0A
(LF)将打印头向下移动到下一行。 (Unicode将其编码为U+000A LINE FEED
。)
在电传打印机和早期技术打印机的时代,人们实际上利用了这两个独立的操作。 通过发送一个CR而不用一个LF来跟随它,你可以在你已经打印的行上打印。 这允许了重音,粗体和下划线等效果。 某些系统多次套印以防止在硬拷贝中看到密码。 在早期的串行CRTterminal上,CR是控制光标位置以更新屏幕上已有文本的方法之一。
但是大多数情况下,你只是想去下一行。 而不是要求一对控制字符,一些系统只允许一个或另一个。 例如:
- Unix变体(包括Mac的现代版本)仅使用LF字符来表示换行符。
- 旧的(pre-OSX)Macintosh文件仅使用CR字符来表示换行符。
- VMS,CP / M,DOS,Windows和许多networking协议仍然期望:CR LF。
- 使用在NL上标准化的EBCDIC的旧IBM系统 – 甚至不存在于ASCII字符集中的字符。 在Unicode中,NL是
U+0085 NEXT LINE
,但实际的EBCDIC值是0x15
。
为什么不同的系统select不同的方法? 只是因为没有通用的标准。 如果您的键盘可能会显示“Enter”,那么旧的键盘会用来说“Return”,这是回车的简称。 实际上,在串口terminal上,按Return键实际上是发送CR字符。 如果你正在编写一个文本编辑器,那么从terminal进来的时候使用这个字符是很有诱惑力的。 也许这就是为什么老年人使用的只是CR。
现在我们有了标准 ,有更多的方法来表示换行符。 虽然在野外极其罕见,但Unicode有如下新字符:
-
U+2028 LINE SEPARATOR
-
U+2029 PARAGRAPH SEPARATOR
即使在Unicode出现之前,程序员也需要简单的方法来表示一些最有用的控制代码,而不用担心底层的字符集。 C有几个转义序列来表示控制代码:
-
\a
(用于警报)打电话铃或使terminal发出嘟嘟声 -
\f
(换页),移到下一页的开头 -
\t
(用于制表符),将打印头移动到下一个水平制表位置
(这个清单是故意不完整的。)
这个映射发生在编译时 – 编译器看到\a
并放置任何用于响铃的魔法值。
请注意,大多数这些助记符与ASCII控制代码有直接的关系。 例如, \a
会映射到0x07 BEL
。 为主机字符集(例如EBCDIC)使用非ASCII的系统可以编写编译器。 大多数具有特定助记符的控制代码可以映射到其他字符集中的控制代码。
好哇! 可移植性!
好吧,差不多。 在C中,我可以编写printf("\aHello, World!");
响铃(或嘟嘟声)并输出消息。 但是如果我想在下一行打印一些东西,我仍然需要知道主机平台需要移到下一行输出。 CR LF? CR? LF? NL? 别的东西? 这么多的便携性。
C有两种I / O模式:二进制和文本。 在二进制模式下,无论发送什么数据都照原样传输。 但是在文本模式下, 运行时转换会将特殊字符转换为主机平台所需的新行(反之亦然)。
太好了,那么特别的人物是什么?
那么,这也是依赖于实现的,但是有一种独立于实现的方式来指定它: \n
。 它通常被称为“换行符”。
这是一个微妙而重要的点: \n
在编译时被映射到一个实现定义的字符值,然后在运行时再次映射到文本模式下的底层平台所需的实际字符(或字符序列)移动到下一行。
\n
与所有其他反斜杠文字不同,因为涉及到两个映射。 这个两步映射使得\n
与\r
明显不同,它只是一个到CR的编译时映射(或者底层字符集中最相似的控制代码)。
这使许多C和C ++程序员绊倒。 如果您要轮询其中的100个,至less有99个会告诉您\n
意味着换行。 这不完全正确。 大多数(也许是所有的)C和C ++实现都使用LF作为\n
的神奇中间值,但这是一个实现细节。 编译器使用不同的值是可行的。 事实上,如果主机字符集不是ASCII的超集(例如,如果它是EBCDIC),那么\n
几乎肯定不是LF。
所以,在C和C ++中:
-
\r
实际上是一个回车。 -
\n
是一个魔法值,它在运行时被转换(在文本模式下)到/从主机平台的换行符语义。 -
\r\n
几乎总是一个可移植性错误。 在文本模式下,这将被转换为CR,然后是平台的换行顺序 – 可能不是预期的。 在二进制模式下,这将被转换为CR,然后是一些可能不是 LF的魔法值 – 可能不是什么意图。 -
\x0A
是表示ASCII LF的最便携的方式,但您只想在二进制模式下执行此操作。 大多数文本模式的实现将像\n
那样对待。
- “\ r”=>返回
-
“\ n”=>换行符或换行符(语义)
-
基于Unix的系统只使用“\ n”来结束一行文本。
- Dos使用“\ r \ n”来结束一行文本。
- 其他一些机器只使用“\ r”。 (Commodore,Apple II,OS X之前的Mac OS等)。
简而言之,\ r有ASCII值13(CR),\ n有ASCII值10(LF)。 Mac使用CR作为行分隔符(至less,它以前做过,我不知道现代Mac)* nix使用LF和Windows使用两个(CRLF)。
\r
用来指向一行的开始,可以replace那里的文本,例如
main() { printf("\nab"); printf("\bsi"); printf("\rha"); }
产生这个输出:
hai
\n
是换新的一行。
除了@Jon Skeet的回答:
传统上Windows已经使用了\ r \ n,Unix \ n和Mac \ r,但是更新的Mac使用\ n,因为它们是基于Unix的。
在C#中,我发现他们在string中使用\ r \ n。
\ r是回车; \ n是新行(换行符)…取决于操作系统的意思。 请阅读这篇文章 ,了解更多关于'\ n'和'\ r \ n'的区别。
\ r用于回车。 (ASCII值是13)\ n用于换行。 (ASCII值是10)