这令人困惑,因为 Windows 和 Unix 的行为不同:
linux-$ printf "abc\ndefg\rhij\r\n" | hexdump -C
00000000 61 62 63 0a 64 65 66 67 0d 68 69 6a 0d 0a |abc.defg.hij..|
0000000e
如您所见,程序只是按照指示将这些字符 (0x0d - CR, 0x0a - LF) 发送到管道 (| hexdump -C)、文件(您将在其中使用 dos2unix 或unix2dos),或终端。
如果我们将它发送到终端,那么您就会开始看到不同之处:
linux-$ printf "abc\ndefg\rhij\r\n"
abc
hijg
这是来自配置为使用常规 Unix 约定(与语义不同)的 Linux 上的 URXVT。
在这个约定中,\n 被终端视为\r\n,所以abc\ndefg\rhij\r\n 实际上变成了abc\r\ndefg\rhij\r\n。
这就是为什么当终端显示它时,它打印abc,返回到行首,下降到下一行,打印defg,返回到行首,不下降到下一行行,用hij 覆盖该行的前三个字符,然后返回到行首,然后跳到下一行。
所以回答你的具体问题:
但是在使用换行的时候,光标不会到下一行的开头吗?
“光标”假定处理输出的设备是终端。所以答案取决于终端是如何配置的。在 Unix 终端上答案是“是”。 Windows 和 DOS 终端未配置为执行此操作。
那为什么人们说 lf 只将光标移动到下一行而不转到开头,而 crlf 转到行首然后转到下一行。
因为这就是 Windows 和 DOS 终端处理 LF 和 CRLF 的方式。
当使用任何编程语言如 C 打印“Hello\nHELLO”时,它不会在下一行的开头自动打印 HELLO 吗?
啊,这是个好问题。有个鬼鬼祟祟的小规则there:
在文本模式下写入文件、设备节点或套接字/fifo 时,\n 被透明地转换为系统使用的本机换行符序列,该换行符序列可能超过一个字符。在文本模式下阅读时,本机换行序列被翻译回\n。在二进制模式下,不进行翻译,直接输出\n产生的内部表示。
你看,Unix 终端上的约定(即默认配置)是将\n 视为\r\n,因此从 C 向 Unix 终端发送Hello\nHELLO 会导致它也返回到开头遇到\n时的行。
另一方面,在 Windows 上,所有这些打印函数都会静默地将您的输入 \n 转换为输出 \r\n,并且终端会按照您的预期分别处理它们。
在旧的 Mac 上,换行符是 \r,\n 被静默转换为 \r,当光标返回到行首时,终端会跳到下一行。
那么CRLF和LF有什么区别呢?
- LF 是跨所有系统的“新行”编程语言标准,而 CR 是显示文本的程序的产物,通常是终端。
- 某些系统 (Windows) 在某些情况下会静默地将 LF 转换为 CRLF,但会定期处理 CR。
- 某些系统(旧 Mac)在某些情况下会静默地将 CR 转换为 CRLF,但会定期处理 LF。
- 某些终端 (Unix) 将 LF 视为 CRLF,但会定期处理 CR。
- 某些终端(旧 Mac)将 CR 视为 CRLF,但会定期处理 LF。