编程基础知识
换行符:CR、LF、CRLF
换行由两个控制字符组合或单独承担:
- CR(Carriage Return,回车):字符
\r,ASCII 十进制 13,十六进制0x0D。打字机时代把打印头送回行首,光标不往下走。 - LF(Line Feed,换行):字符
\n,ASCII 十进制 10,十六进制0x0A。打字机把纸卷一行,打印头仍停在原列。
CRLF 是两者连用:\r\n(先回车再换行)。
各系统用哪一种
历史原因造成三套主流约定:
- DOS、Windows: CRLF,即
\r\n - UNIX、Linux: LF,即
\n - 经典 Mac OS(OS X 之前):CR,即
\r
现行 macOS(从 OS X 起,内核是 Darwin)已经改成和 UNIX 一样用 LF。再把「Mac 等于 \r」写进新项目,是过期说法;只有处理极老的 Mac 文本时才会碰到单独的 CR。
C、C++ 等运行库在 文本模式 打开文件时,会按当前平台做换行转换:程序在 Windows 上写出的文本常常是 CRLF,在 Linux 上常常是 LF。用二进制模式打开则原样读写,不做转换。
JavaScript 的 fs.readFile 默认按字节读,不会把 \r\n 收成 \n。
混用会出什么问题
在一个平台上打开另一种换行的文件,编辑器往往仍显示正常,工具链却不认。
- 源码混用 CRLF 和 LF 时,有的编译器、预处理器会报错,或把
\r当成普通字符留在字符串里。 - Unix 上跑带 CRLF 的 shell 脚本,常见报错是
$'\r': command not found:解释器把\r当成命令名的一部分。 Makefile、.env、以行为单位的协议(HTTP 头本身规定 CRLF)对换行更敏感。
很多编辑器可以查看并转换全文的换行格式(VS Code 右下角的 CRLF 或 LF 即可切换)。Git 仓库里应靠 .gitattributes 把策略写死,而不是每人手工点一次。
用 FTP 传文本时,ASCII 模式会按两端操作系统改换行,文件字节数会变;要保持原文件,用 二进制(bin)模式。不要指望 FTP 帮你「统一换行」,那只是传输过程中的隐式改写。
Git 里怎么约定
Git 可以在检出、提交时转换换行,配置不当会制造满屏「整文件都改了」的 diff。
core.autocrlf:Windows 上有人设true(检出 CRLF、提交 LF),Unix 上常用input(提交时把 CRLF 收成 LF)。同一仓库里各人设置不同,就会反复改换行。- 更稳妥的是在仓库根目录写
.gitattributes,例如* text=auto,让 Git 按文件是否为文本来规范化,不依赖本机autocrlf。 - 编辑器侧可用
.editorconfig的end_of_line = lf(或crlf)与仓库策略对齐。
协作仓库应选定 一种 换行(开源项目几乎都用 LF),在 Git 和编辑器里同时锁住,而不是依赖「运行库会自动决定」。