4

我想标题不言自明。

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

文件内容:

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。

我希望我说清楚了。谢谢。

4

2 回答 2

3

这就是以文本和二进制模式读取文件的区别。

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

唯一的判断方法是以两种不同的方式读取文件,看看是否有 CRLF 对或大小不同,或者实际上只是看看是否有 LF,因为我认为当前的任何主要操作系统都没有使用它作为一行enfing。

于 2012-10-28T11:35:50.197 回答
2

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

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

...

_setmode(fileno(stdin), _O_BINARY);

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

于 2012-10-28T11:38:01.437 回答