在 C 语言中,我们有几个常见的转义序列:
\r
用于回车 (CR) - 相当于执行 '\015'
\n
通常被描述为换行(LF),但我明白'
' 将根据 CRLF 的要求翻译成字符串(取决于操作系统) - 这相当于执行 "\015\012"
。特别是如果我喜欢 printf
或 fprintf
。
是否有真正的换行字符的转义码不会被翻译,或者当我不想翻译它时我是否坚持使用
'\012'
?
C 编译器中没有翻译。一串[这些都是等价的]:
// (1) these are all equivalent to a string of newline of length 1:
"\n"
"\x0a"
"\012"
// (2) these are all equivalent to a string of carriage return of length 1:
"\r"
"\x0d"
"\015"
// (3) these are all equivalent to a string of CRLF of length 2:
"\r\n"
"\x0d\0x0a"
"\015\012"
在 POSIX 系统下输出到终端时,TTY 驱动程序会将 case (1) 以 Cooked 模式转换为 CRLF。这可以通过一些 TTY
ioctl
呼叫来更改。 IIRC,与 Windows 类似(?)。但是,[再次]IIRC,Windows 有一些必须完成的特定于 Windows 的调用,因为转换是在非常低的层完成的。
在 POSIX 系统下写入文件时,不会进行任何翻译。
但是,在 Windows 下写入文件时,情况 (1) 会被操作系统翻译为 CRLF 以便正常打开 [因为默认为“文本”模式]:
open(file,O_WRONLY);
fopen(file,"w");
要抑制在Windows下对于情况(1)的翻译,请以“二进制”模式打开文件:
open(file,O_WRONLY | O_BINARY);
fopen(file,"wb");
二进制模式也适用于以读取模式打开。而且,对于 POSIX,它[实际上]是一个无操作并且被忽略。有/没有二进制选项,在 POSIX 下,将以二进制模式打开,因为 POSIX 没有文件的“文本模式”。
因此,为了 POSIX/Windows 之间的可移植性,这是用于抑制翻译的模式。
@Barmar 是对的:
\n
和 \012
是完全相同的位。 Windows 计算机上的普通 LF 和 CRLF 之间的区别在于打开要写入的设备的方式。例如,如果您在 cygwin 下对终端执行 printf
操作,则可以 stty
更改为原始模式。否则,这将取决于您所使用的 C 库的具体情况。
编辑 对于使用 msvcrt 的 Win32,使用
fopen(..., "b")
,“涉及回车符和换行符的翻译被抑制”(来自 MSDN)。相比之下,在文本模式下,“换行符在输出时被转换为回车换行组合”(相同来源)。
因此,为了回答最初的问题,在每个平台上、每个输出例程中,没有一个转义序列在输出上始终是
\012
。
历史:
旧的大型计算机的终端通常通过慢速连接进行连接。终端是打字机。用户输入一行后,他们按回车键(就像在旧打字机上一样)。这是主机处理线路的信号。一旦主机接收并处理了该行,它就会发送一个换行符。打字机的纸张现在上升了一行,通知用户系统已准备好接收另一行。
基于分时的 Unix 复制了这种行为。
(但是我还是不确定Unix下存储的是LF,还是CR——从上面看,应该是CR,系统加上了LF。)
Windows,不是分时的,只需将CR和LF放入文件即可。
万一有人在多年后偶然发现这个帖子 - 我的观点与这里的许多人不同。
在 ASCII 世界中:
CR 字符是十进制 13,或十六进制 0D,或
LF 字符是十进制 10,或十六进制 0A,或
Windows 行以 CRLF 对结束,或者 .
Linux 行仅以 LF 结尾,或者 .
Mac 行仅以 CR 结尾,或者 。我认为当时的 8 位 PC(如 TRS-80)也使用了这个。
是换页符的转义序列。十进制 12,十六进制 0C 是新行的转义序列。十进制 10,十六进制 0A 是回车符的转义序列。十进制 13,十六进制 0D
换页是十进制 12、十六进制 0C 或转义序列。它不相当于 .
这是一篇很好的支持文章:https://en.cppreference.com/w/cpp/language/escape