8

很简单地说,我有以下代码片段:

FILE* test = fopen("C:\\core.u", "w");
printf("Filepointer at: %d\n", ftell(test));
fwrite(data, size, 1, test);
printf("Written: %d bytes.\n", size);
fseek(test, 0, SEEK_END);
printf("Filepointer is now at %d.\n", ftell(test));
fclose(test);

它输出:

Filepointer at: 0
Written: 73105 bytes.
Filepointer is now at 74160.

这是为什么?为什么写入的字节数与文件指针不匹配?

4

4 回答 4

19

由于您以文本模式打开文件,因此它将行尾标记(例如 LF)转换为 CR/LF。

如果您在 Windows 上运行,则可能会出现这种情况(并且您可能是,因为您的文件名以 开头"c:\")。

如果您以"wb"模式打开文件,我怀疑您会发现数字相同:

FILE* test = fopen("C:\\core.u", "wb");

C99 标准中有这样的说法7.19.5.3 The fopen function

参数模式指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。否则,行为未定义。

r打开文本文件以读取
w截断为零长度或创建文本文件以写入
a附加;打开或创建文本文件以在文件末尾写入
rb打开二进制文件以读取
wb截断为零长度或创建二进制文件以写入
ab追加;打开或创建二进制文件以在文件末尾写入
r+打开文本文件以进行更新(读取和写入)
w+截断为零长度或创建文本文件以进行更新
a+追加;打开或创建文本文件以进行更新,在文件末尾写入
r+brb+打开二进制文件以进行更新(读取和写入)
w+bwb+截断为零长度或创建二进制文件以进行更新
a+bab+追加;打开或创建二进制文件进行更新,在文件末尾写入

您可以看到它们区分wwb。我认为不需要实现来区别对待这两者,但对二进制数据使用二进制模式通常更安全。

于 2008-09-28T02:23:13.240 回答
0

fwrite 返回什么?通常返回值应该是写入的字节数。另外,在 fseek 之前 ftell() 的回答是什么?

了解什么操作系统、C 编译器版本和 C 库可能会有所帮助。

于 2008-09-29T04:26:58.083 回答
0

文件指针是 cookie。它没有价值。您唯一可以使用它的就是寻找文件中的相同位置。我什至不确定 ISO C 是否保证 ftell 返回递增的值。如果您不相信这一点,请查看不同的 seek() 模式。它们的存在正是因为位置不是简单的字节偏移。

于 2008-09-29T12:32:17.930 回答
0

windows 实际上不会在没有刷新和 fsync 的情况下将所有数据写入文件。也许这就是为什么

于 2010-02-12T23:55:54.363 回答