在C中,我通常一次读取一个字符的文本文件(例如,在FSM的循环中,同时进行标记和解析)。不幸的是,一些操作系统使用不同的方法来标记一行的结尾,例如, Unix("\n"
),Mac OS("\r"
)和DOS / Windows("\r\n"
)。
因此我的问题是:如何正确检测来自不同操作系统的文本文件中的行结尾?
我目前的做法是将'\r'
视为'\n'
并忽略空行。不幸的是,只有空行不会改变底层文本的语义,这种方法才有效。
我不想“检测”每个文件的行结束样式,我当然不希望基于#ifdef
或其他类型的条件编译的解决方案。是否有任何有效的解决方案?
答案 0 :(得分:4)
我通常不建议一次读取一个字符的文件,但对于你的情况,我建议你“偷看”一个字符前面使用以下逻辑......
if c == '\r'
p = peek
if p == '\n'
read next c
您无法真正相信所有文件具有一定的亲和力,甚至文件本身遵循相同的约定,因此您应该为所有情况编码。在这种情况下,如果您看到\ r \ n 可能看到\ n,并且您是否使用了下一个字符并继续。
答案 1 :(得分:1)
不幸的是,如果文件已被传递,或者使用允许您指定行结尾的编辑器进行编辑,或者出于任何其他类似原因,则文件可以具有混合行结尾。 确定文件的“<”>行行结束样式可能需要投票 - 以风格 X 结尾的大多数行都会获胜。
我所做的是
将\r
视为换行符。如果下一个
char \n
丢弃它。 (如果
下一个字符不是\n
\r
算作换行符)
将\n
视为一个
换行,除非你扔掉它,因为(1)
答案 2 :(得分:1)
我通常的做法是将'\n'
视为行终止符,如果前一个字符是'\r'
,则将其删除(通常我最终用0覆盖其中一个或另一个)。如果您还想支持旧版Mac文本文件('\r'
- 仅限换行符),那么您可以采用单独'\r'
,孤独'\n'
或{{1}对的方法作为换行符。