我应该指望换行符是什么字符?

What character should I count on the newline character being?

提问人:user129393192 提问时间:8/4/2023 更新时间:8/4/2023 访问量:53

问:

参考:为什么文本文件应该以换行符结尾?

我正在编写一个文本编辑器,我想在 macOS 和 Linux 上运行并符合 POSIX。在解析原始文本文件时,我应该期待(旧 MacOS)还是(新 MacOS 和 Linux)还是应该期待 (Windows)?CRLFCR+LF

C Linux macOS 文件 解析

评论

3赞 Barmar 8/4/2023
当您以文本模式写入文件时,会自动转换为当前操作系统的相应换行符。所以你不应该自己处理这个问题。\n
1赞 Ian Abbott 8/4/2023
@Barmar 但是,如果文本编辑器需要编辑非本机文本文件,则不适用。
2赞 Jonathan Leffler 8/4/2023
换行符是换行符。如果您在 Windows 上以文本模式打开文件,I/O 库会将 CRLF 行尾转换为(这就是为什么标准 C 语言对文本文件可以做什么有限制的原因,尽管这些限制在类 Unix 系统上没有实际意义)。如果你想处理这三个,这是高尚的,也是可能的,但是要处理旧的MacOS风格,将需要自定义的行读取代码(标准C不会处理;POSIX将)。使用 或 将处理 CRLF,但您必须删除 .'\n''\r'fgets()getdelim()fgets()getline()'\r'
1赞 Barmar 8/4/2023
@IanAbbott 是的,GNU Emacs 也是如此。寻找第一个 CR 或 LF,并保留它。只有在创建新文件时才需要显式配置。
2赞 Ian Abbott 8/4/2023
@Barmar <holywar>是的,但是 Vim 比 GNU Emacs.</holywar 更好>

答:

0赞 Eric Postpischil 8/4/2023 #1

在解析原始文本文件时,我应该期待(旧 MacOS)还是(新 MacOS 和 Linux)还是应该期待 (Windows)?CRLFCR+LF

您是否有理由相信您的软件的任何用户都不会创建包含任意字节序列的文件,然后要求您的软件对其进行操作?

您是否有理由相信您的软件的任何用户都不会将文件从某些外国系统或古老的存储介质复制到他们的主系统上,然后要求您的软件对其进行操作?

当用户这样做时,你希望你的软件做什么?

直接回答,你应该期待吗?不,因为您不知道用户会做什么。你应该为此做好准备吗?是的,因为你不知道用户会做什么。

评论

0赞 user129393192 8/4/2023
所以我的问题是,我应该指望换行符是什么?我在编码方面问,如果不清楚的话。似乎该库具有特殊的功能,可以转换为 Windows 上的或任何操作系统的适当措施,但我正在处理 POSIX 库,所以这是我的问题,我是否应该明确地检查 ,这反过来(我假设)将对应于 .我想知道这种行为是否可移植,假设 -> 和 -> 的映射。这是我的问题。\nstdio\nCR + LFreadwrite\rCR\nLF\rCR
0赞 Eric Postpischil 8/4/2023
什么是不清楚的?“是”意味着“是”。关于你是否应该为各种事情做准备的问题的答案是肯定的。什么都不指望。为一切做好准备。
0赞 user129393192 8/4/2023
不,这不是我的问题。我的问题是:在编码方面是否映射到和到。要么你认为这是显而易见的,要么你没有看到这是我的问题。无论哪种方式,都没有得到明确的回答。问题不在于我是否应该为各种事情做准备。\nLF\rCR
0赞 Eric Postpischil 8/4/2023
地图在哪里?你说你要使用 POSIX 和 .它们不会像 C 标准库例程那样映射文本流。如果使用 C 标准库文本流,则它们会在 C 模型之间映射,其中包含字符终止行和主机环境中的某些行表示形式,这在技术上特定于 C 实现。您要解析哪些“原始文本文件”以及使用哪些例程?它们是否仅由主机系统上的文本文件工具创建原始文本文件?readwrite\n
0赞 user129393192 8/4/2023
还行。我会尽量说得更明确,也许我选择的词很糟糕。如果我这样做了,并且此语句的计算结果为 true,我是否刚刚收到了 ?同样,如果我这样做了,这是真的,那总是一个吗?read(STDIN_FILENO, buf, 1) && buf == '\n'LFread(STDIN_FILENO, buf, 1) && buf == '\r'CR
2赞 chqrlie 8/4/2023 #2

如果您希望您的编辑器具有多功能性并以合理的方式处理来自各种系统的文件,您应该接受行结束序列的所有 3 种可能性:单个 LF 字节用于 unix 系统,包括 linux 和 OS/X,单个 CR 字节用于在较旧的 macOS 版本上创建的文件,以及序列 CR+LF 用于在 Microsoft Windows 上生成的文件, MS/DOS 和原始的 CP/M 系统。

您可以通过扫描文件的开头来自动检测行尾风格:如果您找到 CR+LF 序列,则您有一个 Windows 文件,如果您有 CR 字节后跟 LF,则是一个 oldmac 文件,如果您有 LF 字节,则它是一个 unix 文件,如果上述都不存在,它要么是二进制文件,要么是没有行尾的单行文本文件。对于这些,请使用当前执行平台的默认值。

是保留行尾风格以进行修改,还是将行尾序列转换为本地风格是一个设计决策。在 Quick Emacs 中,我选择保留行尾风格,并让用户使用特定命令按需执行转换。

在任何情况下,您都应该以二进制模式打开文件进行读取和写入,并在程序中显式处理行尾。