2011-04-08 50 views
2

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

因此我的问题:如何正确检测跨越文本文件的行结束,从不同的操作系统?

我目前的做法是把'\r''\n'而忽略空行。不幸的是,这种方法只有在空行不会改变底层文本的语义时才起作用。

我不想“检测”每个文件的行结束风格,我当然不希望基于#ifdef或其他类型的条件编译的解决方案。还有没有有效的解决方案?

+0

你可以简单地忽略/丢弃任何“\ r”字符? – Brendan 2011-04-08 23:02:37

+0

@Brendan:截至目前,我一直都能这样做。但我可以想象一个空行实际上有一些含义的场景(例如,从内容中分离标题)。在这种情况下,如果我将Windows文本文件提供给程序,则会错误解释其内容,因为“\ r \ n”(一行结尾)被视为“\ n \ n”(两行结尾)。 – Philip 2011-04-08 23:05:10

回答

4

我通常不建议读文件一个字符在一个时间,但对于你的情况,我建议你“窥视”提前一个字符使用下面的逻辑...

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

你不能真的相信全部文件具有一定的亲和力,或者甚至文件在整个本身遵循相同的约定,因此您应该编码所有情况。在这种情况下,如果你看到\ r你可能看到一个\ n,如果你消耗下一个字符,继续前进。

+0

这也是我通常的做法,+1 – Milan 2011-04-08 23:05:31

+0

反对一次读取一个字符的原因是什么?性能? – Philip 2011-04-08 23:11:13

+0

@菲利普:表现和工作分工。我发现在更高抽象层次上的工作数据通常会使代码更易于扩展和维护。 – 2011-04-08 23:12:58

1

不幸的是,如果一个文件已经被传递,或者编辑器允许你指定行结束符,或者出于任何其他类似的原因,文件可以有混合行尾。 确定一个文件“中的”行结束样式可能是进行表决的问题 - 在风格X胜结束大部分线路。

我所做的是

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

  2. 治疗\n作为 换行,除非你把它扔了监守(1)

+0

我喜欢(并提高了)你的答案,但我接受了来自Andrew White的一个(这大致意味着相同),因为评论中的附加信息。希望你不介意:) – Philip 2011-04-08 23:32:03

+0

@Philip - 当然不是! – 2011-04-08 23:43:02

1

我通常的做法是将'\n'作为行终止符,如果前一个字符是'\r',则将其删除(通常我最终将覆盖0或其中一个)。如果你也想支持虽然传统MAC文本文件('\r' - 只换行),那么你可以采取治疗或者孤独'\r',孤独'\n',或对"\r\n"当做一个换行符的方法。

相关问题