为啥建议在源文件末尾有空行?

Posted

技术标签:

【中文标题】为啥建议在源文件末尾有空行?【英文标题】:Why is it recommended to have empty line in the end of a source file?为什么建议在源文件末尾有空行? 【发布时间】:2011-01-18 06:44:00 【问题描述】:

一些代码风格工具推荐这个,我记得看到一些 unix 命令行工具警告缺少空行。

有一个额外的空行的原因是什么?

【问题讨论】:

如果文件不以换行符结尾,某些工具将无法工作。这与末尾有一个空行(即 2 个换行符)不同。 你的意思是空行(\n\n)还是换行\n cat shell 上的文件,你就会知道为什么。如果你的文件让我的 shell 提示出现在它应该出现的位置(在行首)之外的任何其他地方,我可能会讨厌你。 ;) 更好(更一般)的答案是一般的文本文件:: ***.com/questions/729692/… 我的问题是,在这个时间点上,这个建议仍然有用吗? 【参考方案1】:

如果文本文件中的最后一行数据没有以换行符或回车符/换行符组合终止,则许多旧工具会出现异常。他们忽略该行,因为它以 ^Z (eof) 终止。

【讨论】:

感谢您的回答!任何可能表现出这种行为的流行工具示例? @NickM 几乎所有接受文本输入或读取文本文件的 POSIX/Unix 命令行工具都假定在文件末尾以行结尾 (\n)。几个文本编辑器,如 Vim,和几个编译器(特别是 C++ 和 Python)会发出警告。 (在 C++ 的情况下,标准明确要求这样做。) 所以你的意思是......这是一个货物崇拜 然而你可以在最后一行有文字,问题提到了一个空行\n\n【参考方案2】:

如果您尝试将两个文本文件连接在一起,如果第一个文件以换行符结尾,您会更开心。

【讨论】:

你什么时候连接文件,并且在连接过程中不能选择在中间添加换行符? @Rudey 例如。当你做cat file1 file2 file3【参考方案3】:

除了当您在文本编辑器中移动到文件末尾时,它是一个更好的光标位置。

文件末尾有一个换行符可以简单地检查文件是否被截断。

【讨论】:

文件可能会被截断,你甚至永远不会知道 没有什么能阻止文件在中间某处有换行符,并且文件很容易被截断。 @Rudey 是的,但它是一个很好的免费启发式方法。随机截断不太可能导致结尾换行。【参考方案4】:

如果您按照与 Why are trailing commas allowed in a list? 相同的推理附加到文件,也可以为更清晰的差异创建一个参数

以下内容是从链接资源中复制(并稍作修改)的:

变化:

s = [
  'manny',
  'jack',
]

到:

s = [
  'manny',
  'jack',
  'roger',
]

只涉及 diff 中的一行更改:

  s = [
    'manny',
    'jack',
+   'roger',
  ]

这比省略尾随逗号时更令人困惑的多行差异:

  s = [
    'manny',
-   'jack'
+   'jack',
+   'roger'
  ]

【讨论】:

【参考方案5】:

文件末尾的空行出现,以便从输入流中进行标准读取将知道何时终止读取,通常返回 EOF 表示您已到达末尾。大多数语言都可以处理 EOF 标记。出于这个原因,在 DOS 下,EOF 标记是 F6 键或 Ctrl-Z,对于 *nix 系统,它是 Ctrl-D。

大多数(如果不是全部)实际上会一直读取到 EOF 标记,以便运行时库的从输入读取的函数知道何时停止进一步读取。当您以 Append 模式打开流时,它会擦除​​ EOF 标记并将其写入过去,直到显式调用 close 时,它​​将在该点插入 EOF 标记。

旧工具需要一个空行,后跟 EOF 标记。如今,工具可以处理空行并忽略它。

【讨论】:

^D 不是“EOF 标记”。按 ^D 导致 shell 关闭前台进程组正在读取的管道的写入端,因此从该管道读取返回 EOF。没有“EOF 标记”。 @William Pursell 您错误地将 *NIX 和 Windows 混为一谈。旧版 Windows/DOS 绝对使用通常嵌入在大多数文件末尾的 EOF 标记(26, 0x1a)作为与古代 CP/M 兼容的保留(谁在 1983 年之后使用 CP/M?)。其他“有趣”:\r\n 代替 \n,DOS 调用使用 ASCIIZ 和 ASCII$ 的混合。更糟糕的是,后来在 Windows 上通常会在大多数文本文件的开头插入一个 Unicode 字节顺序标记 (BOM)。可爱的“独特性”。【参考方案6】:

此外,当您修改文件并在文件末尾附加一些代码时 - diff(至少标准配置中的 git diff )将显示您更改了最后一行,而您实际完成的唯一一件事 - 添加了换行符象征。所以 cvs 报告变得不那么方便了。

【讨论】:

【参考方案7】:

这个问题以及大多数现有答案似乎都是基于一种误解。

通常称为“换行符”的 ASCII 控制字符(C 中的 U+000A 换行符,\n开始(Unix 样式)文本文件的新行。它结束文本文件的当前行。如果文本文件的最后一个字符是 U+000A,则在“U+000A”和文件系统的 EOF 标记(无论如何实现)之间没有 一个空行。相反,如果(非空)文本文件的最后一个字符是not U+000A,则文件的最后一行还没有结束——它被称为“不完整”。

用一些例子可能会更清楚:

此文件包含两行完整的文本。它不包含第三个空行。

$ printf 'first\nsecond\n' | xxd
00000000: 6669 7273 740a 7365 636f 6e64 0a         first.second.

文件包含第三个空行。

$ printf 'first\nsecond\n\n' | xxd
00000000: 6669 7273 740a 7365 636f 6e64 0a0a       first.second..

这个文件只包含一个完整的行,加上第二个incomplete行。

$ printf 'first\nsecond' | xxd
00000000: 6669 7273 740a 7365 636f 6e64            first.second

有时你想要一个不完整的最后一行——例如,在 php 脚本的最后一个 ?> 和 EOF 之间有一个换行符,可能会导致额外的空格被发送到渲染的 html 的错误位置(我会链接到具体的例子,但今天早上我没有找到一个例子)。因此,优秀的文本编辑器会在其 UI 中清楚地区分上述所有三种情况。

但是,较旧的文本处理工具通常会错误处理不完整的最后几行。例如,wc 的某些实现不会将不完整的最后一行视为一行,而vi 的某些实现会在不以 1 结尾的文件中静默地添加换行符,无论您想要它还是不是。因此,只有在有特定理由需要它们时才应使用不完整的最后几行。

(注意:据我所知,我刚才所说的一切对于DOS风格的文本文件也是如此,其中两个字节的控制序列U+000D U+000A用于结束一行,而不仅仅是U +000A。)

【讨论】:

【参考方案8】:

某些语言根据输入行定义其输入文件,其中每个输入行是一系列以回车符结尾的字符。如果它们的语法是这样定义的,那么文件的最后一个有效行也必须以回车结束。

【讨论】:

【参考方案9】:

这是因为文本文件的定义。在任何 unix 环境中创建新文本文件时,该文件的内容是 new line character '\n'

没有这个,文件就不会真正被识别为文本文件。现在,一旦我们将代码添加到此文本文件中,它就不会删除 defines a text file itself 的初始新行。

【讨论】:

以上是关于为啥建议在源文件末尾有空行?的主要内容,如果未能解决你的问题,请参考以下文章

Vim 为啥要在文件末尾添加新行?

为啥在 Qt 源代码文件末尾包含“.moc”文件很重要?

为啥我必须费心在每个文件的末尾添加换行符?

JAVA程序命令行中有空格问题

刚学java, 有个问题,若java源文件名称中有空格,比如abc 123.java,这个java文件在命令行窗口怎么编译?

看看这个Java程序 用递归遍历F盘中的所有文件,为啥会有空指针异常。