如何正确识别C中的不同行结尾?

时间:2012-10-28 11:25:37

标签: c ascii line-endings lf

我想这个标题不言而喻。

我正在Windows 7上编写一个C程序,使用g ++和Notepad ++来比较文件内容。

文件内容:

simple
file with lines

文件在Windows样式CRLF中有行结尾。

当我使用此代码计算文件的长度时:

fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);

23

当我将行结尾更改为Unix格式LF(使用Notepad ++)时,我得到 22 长度。

比较两个文件时,这会产生一些问题。这就是为什么我问,如果有办法确定给定的文件是否有LF或CR或CRLF。

我知道我可以区分CR和LF,LF有ascii代码10,CR有ascii代码13.或者LF是'\ n'而CR是'\ r'。

但是当在char之后读取文件char时,我总是得到LF(ascii 10),即使有CRLF。

我希望我说清楚。感谢。

2 个答案:

答案 0 :(得分:2)

这是在文本和二进制模式下读取文件之间的区别。

在文本模式下(使用相关参数fopen( file, "r")然后getc等),所有行结束都被读为一个字符。如果您以二进制模式阅读,例如fopen(file, "rb")然后你会得到实际的字节,你会看到CRLF和CR不同。 fseek将使用实际的字节数,因此可以看到行结尾的差异。

唯一的方法是以两种不同的方式读取文件并查看是否有CRLF对或大小不同,或者实际上只是看看是否有LF,因为我不认为任何当前专业操作系统将其用作线条。

答案 1 :(得分:1)

除了Mark的回答之外,如果您需要为已经打开的文件句柄(例如stdinstdout)执行此操作,则可以使用_setmode()

#include <fcntl.h>
#include <io.h>

...

_setmode(fileno(stdin), _O_BINARY);

如果该文件句柄没有输入或输出,则此工作正常。顺便说一下,_setmode()仅存在于Windows和DOS上;在类Unix操作系统(包括自OS X以来的Mac OS版本)上,文件实际上总是以二进制模式打开,并且fopen(file, "...b")已被接受但没有效果。在这些平台上,行结尾由单个字符\n编码。