行结束符

1. 问题

  • 为何各平台行结束符不同?

  • 跨平台开发应该使用哪种行结束符?

2. 分析

行结束符(end-of-line, EOL)是文本文件中用来表示新行(new line)的间隔,也称作断行符(line break)。

历史上,有三种 EOL:CR、LF 和 CRLF。其中:

  • CR (Carriage Return),即回车;
  • LF (Line Feed),即换行。

古典的 macOS 使用 CR 做 EOL,现在已经改为 LF,所以主流只有 LF 和 CRLF。

哪个更好呢?

从技术的发展史来看,CRLF 更直观。在机械打字机时代,CR 和 LF 分别具有不同的作用:LF 将打印纸张上移一行位置,但是保持当前打字的水平位置不变;CR 则将“Carriage”(打字机上的滚动托架)滚回到打印纸张的最左侧,但是保持当前打字的垂直位置不变,即还是在同一行。 当 CR 和 LF 组合使用时,就是将打印纸张上移一行,且下一个打字位置将回到该行的最左侧。Windows 采用 CRLF,说明微软的人是很技术思维的,就是耿直地认为:行结束就应该像打字机那样先 CR,再 LF。

但从存储和解析的成本来看,LF 更好。所以现在微软在 Windows 11 里也倾向于同时支持两者,目前就连记事本也能识别 LF 格式的 EOL 了。

只使用 LF 可行吗?

能统一肯定是好事!在写代码这件事上,只使用 LF,没啥坑。VS2022、VSCode 都能同时支持 CRLF 和 LF。

3. 实践

  1. git 设置
1
2
git config --global core.autocrlf input
git config --global core.safecrlf true
  1. 工程 .gitattributes 模板
1
2
3
4
*                   text=auto eol=lf
*.sln text eol=crlf
*.vcxproj text eol=crlf
*.vcxproj.filters text eol=crlf

有其它 Windows 特有,并且一保存就自动格式化为 CRLF 的文件,都设成 text eol=crlf

  1. 工程 .editconfig 模板
1
2
3
4
5
6
7
8
# Visual Studio generated .editorconfig file with C++ settings.
root = true

[*.{c++,cc,cpp,cxx,h,h++,hh,hpp,hxx,inl,ipp,tlh,tli}]
charset = utf-8-bom
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
如果您使用微信,也可以关注公众号 UMU618,在公众号文章里评论。