2

在 C 语言中,我通常一次读取一个字符的文本文件(例如,在 FSM 的循环中,同时进行标记和解析)。不幸的是,一些操作系统使用不同的方法来标记行尾,例如 Unix ( "\n")、Mac OS ( "\r") 和 DOS/Windows ( "\r\n")。

因此我的问题是:如何正确检测来自不同操作系统的文本文件的行尾?

我目前的方法是'\r'视为'\n'并忽略空行。不幸的是,这种方法只有在空行不改变底层文本的语义时才有效。

我不想“检测”每个文件的行尾样式,我当然不想要基于#ifdef或其他类型的条件编译的解决方案。是否有任何有效的解决方案?

4

3 回答 3

4

我通常不建议一次读取一个字符的文件,但对于您的情况,我建议您“窥视”一个字符,使用以下逻辑...

if c == '\r'
    p = peek
    if p == '\n'
        read next c

您不能真正相信所有文件都具有一定的亲和力,甚至不能相信文件本身遵循相同的约定,因此您应该针对所有情况进行编码。在这种情况下,如果您看到 \r ,您可能会看到一个 \n 并且如果您确实使用了下一个字符并继续前进。

于 2011-04-08T23:04:48.367 回答
1

不幸的是,如果文件被传递,或者使用允许您指定行尾的编辑器进行编辑,或者出于任何其他类似原因,文件可能具有混合的行尾。确定文件的“the”行结尾样式可能需要投票——以样式X结尾的行数最多。

我所做的是

  1. 视为\r换行符。如果下一个字符被\n丢弃。\n(如果下一个字符不是\r仍然算作换行符)

  2. 视为\n换行符,除非您因为(1)而将其丢弃

于 2011-04-08T23:06:17.320 回答
1

我通常的做法是将'\n'其视为行终止符,如果前一个字符是'\r',则将其删除(通常我最终会用 0 覆盖其中一个或另一个)。如果您还想支持旧版 Mac 文本文件('\r'-only 换行符),那么您可以采用将 lone '\r'、 lone'\n'或对"\r\n"作为换行符的方法。

于 2011-04-08T23:48:12.120 回答