我想这里的每个人都熟悉这句谚语,即所有文本文件都应该以换行符结尾。我已经知道这个“规则”很多年了,但我一直在想——为什么?
当前回答
这源于使用简单终端的早期。换行符用于触发传输数据的“刷新”。
今天,不再需要换行符。当然,如果没有换行符,许多应用程序仍然存在问题,但我认为这是这些应用程序中的一个错误。
然而,如果你有一个需要换行符的文本文件格式,那么你可以得到非常便宜的简单数据验证:如果文件以结尾没有换行符的行结尾,那么你就知道文件已损坏。每行只有一个额外的字节,您可以高精度地检测损坏的文件,几乎不需要CPU时间。
其他回答
为什么文本文件应该以换行符结尾?
因为这是最明智的选择。
获取包含以下内容的文件:,
one\n
two\n
three
其中,\n表示换行符,在Windows上是返回字符,\r\n后跟换行符,因为它很酷,对吗?
这个文件有多少行?Windows说3,我们说3,POSIX(Linux)说文件是残缺的,因为文件末尾应该有一个。
无论如何,你会说它的最后一行是什么?我想任何人都同意三行是文件的最后一行,但POSIX表示这是一个残缺的行。
第二行是什么?哦,这里有第一个强烈的分离:
Windows说两个是因为文件是“用换行符分隔的行”(wth?);POSIX说2,并补充说这是一条真实、诚实的路线。
那么,选择Windows的后果是什么?简单:
你不能说文件是由行组成的
为什么?尝试从上一个文件中取出最后一行并复制几次。。。你得到了什么?这:
one\n
two\n
threethreethreethree
相反,尝试交换第二行和第三行。。。你会发现:
one\n
threetwo\n
因此
您必须说,文本文件是行和\n的交替,以行开始,以行结束
这真是一口,对吧?
你想要另一个奇怪的结果?
你必须接受一个空文件(0字节,实际上是0位)是一个单行文件,神奇的是,因为它们在微软很酷
这真是太疯狂了,你不觉得吗?
POSIX选择的后果是什么?
顶部的文件有点残缺,我们需要一些黑客来处理它。
是认真的
在前面的文本中,我是挑衅性的,因为处理缺少结尾的文本文件会迫使您使用特殊的滴答声/黑客来处理它们。你总是需要一个if/else来让事情运转起来,其中处理残缺行的分支只处理残缺行,所有其他行都采用另一个分支。这有点种族主义,不是吗?
我的结论
我赞成POSIX对行的定义,原因如下:
文件自然被认为是一系列行一行不应该是这样或那样的,这取决于它在文件中的位置空文件不是单行文件,拜托!您不应该被迫对代码进行黑客攻击
是的,Windows确实鼓励您省略后面的\r\n。如果需要下面的两行文件,则必须省略尾部,否则文本编辑器会将其显示为三行文件:
最后缺少换行符的文件还有一个实际的编程问题:read-Bash内置(我不知道其他read实现)无法按预期工作:
printf $'foo\nbar' | while read line
do
echo $line
done
这只打印foo!原因是,当read遇到最后一行时,它将内容写入$line,但返回退出代码1,因为它已到达EOF。这打破了while循环,因此我们永远无法到达echo$line部分。如果要处理这种情况,必须执行以下操作:
while read line || [ -n "${line-}" ]
do
echo $line
done < <(printf $'foo\nbar')
也就是说,如果由于文件末尾的非空行导致读取失败,则执行回显。当然,在这种情况下,输出中将有一个额外的换行符,而输入中没有。
我个人喜欢源代码文件末尾的新行。
它可能起源于Linux或所有UNIX系统。我记得有编译错误(如果我没弄错的话是gcc),因为源代码文件没有以空的新行结尾。为什么会这样呢。
为什么(文本)文件应该以换行符结尾?
正如许多人所表达的,因为:
许多程序运行不好,或者没有它就会失败。即使能很好地处理文件的程序缺少结尾“\n”,该工具的功能也可能无法满足用户的期望——在这种情况下,这一点可能不清楚。程序很少禁止最后的“\n”(我不知道有)。
然而,这引出了下一个问题:
代码应该如何处理没有换行符的文本文件?
最重要的是,不要编写假设文本文件以换行符结尾的代码。假设文件符合某种格式会导致数据损坏、黑客攻击和崩溃。例子://错误的代码while(fgets(buf,buf大小,instream)){//如果没有\n,buf[]被截断,会发生什么buf[strlen(buf)-1]=“\0”;//尝试删除尾部\n...}如果需要最后一个结尾“\n”,请提醒用户该结尾不存在以及所采取的操作。IOW,验证文件的格式。注意:这可能包括对最大行长度、字符编码等的限制。清楚地定义,文档,代码对缺少final“\n”的处理。尽可能不要生成缺少结尾“\n”的文件。
这可能与以下两者之间的差异有关:
文本文件(每行应该以行尾结尾)二进制文件(没有真正的“行”可言,必须保留文件的长度)
如果每一行都以行尾结尾,这就避免了,例如,连接两个文本文件会使第一行的最后一行与第二行的第一行对齐。
此外,编辑器可以在加载时检查文件是否以行尾结尾,将其保存在本地选项“eol”中,并在写入文件时使用该选项。
几年前(2005年),许多编辑(ZDE、Eclipse、Scite…)确实“忘记”了最后的EOL,这并不是很受欢迎。不仅如此,他们还错误地将最后的EOL解释为“开始一行”,实际上开始显示另一行,就好像它已经存在一样。与在上述编辑器之一中打开文本文件相比,这在“适当”的文本文件中是非常明显的,该文件具有良好的文本编辑器(如vim)。它在文件的最后一行下面显示了一行。你会看到这样的情况:
1 first line
2 middle line
3 last line
4
推荐文章
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- 如何删除文件中的特定行?
- 在Bash中获取日期(比当前时间早一天)
- Linux: kill后台任务
- 使用Java重命名文件
- 在OSX中永久设置PATH环境变量
- 如何从Python包内读取(静态)文件?
- 如何在C程序中获取当前目录?
- 为什么我得到“Pickle - EOFError: run out of input”读取一个空文件?
- 如何在Bash中逐行合并两个文件
- Awk不打印换行符
- 写字符串到文本文件,并确保它总是覆盖现有的内容。
- 如何从远程SSH会话发送数据到本地剪贴板
- 我如何得到bash完成工作与别名?
- 从另一个文件导入变量?