C 文件结尾*指针不等于写入数据的大小

C 文件结尾*指针不等于写入数据的大小,c,fopen,fwrite,ftell,C,Fopen,Fwrite,Ftell,简单地说,我有以下代码片段: 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

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

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.

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

因为您是在文本模式下打开文件,它会将行尾标记(如LF)转换为CR/LF

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

如果您在
“wb”
模式下打开文件,我怀疑您会发现数字相同:

FILE* test = fopen("C:\\core.u", "wb");
C99标准在
7.19.5.3 fopen函数中有这样的表述:

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

r
打开文本文件进行阅读
w
截断为零长度或创建用于写入的文本文件
a
append;打开或创建文本文件,以便在文件末尾写入
rb
打开二进制文件进行读取
wb
截断为零长度或创建二进制文件进行写入
ab
append;打开或创建二进制文件,以便在文件末尾写入
r+
打开文本文件进行更新(读写)
w+
截断为零长度或创建文本文件进行更新
a+
append;打开或创建文本文件进行更新,在文件末尾写入
r+b
rb+
打开二进制文件进行更新(读写)
w+b
wb+
截断为零长度或创建二进制文件进行更新
a+b
ab+
追加;打开或创建二进制文件进行更新,并在文件末尾写入


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

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


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

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

windows实际上不会在没有刷新和可能的fsync的情况下将所有数据写入文件。也许这就是我建议不要在fopen()参数中使用NT样式路径的原因。Windows还支持POSIX路径,它是可移植的,不需要转义“\”。是的,但它们必须以某种方式实现。即使标准中没有指定,文件指针在许多实现中也只是字节偏移量,所以说它“没有价值”太迂腐了。它不是cookie。这是二进制模式下的字节偏移量。文本模式是地狱,几乎不能保证任何东西都能正常工作,根本不应该使用它。@R请引用C标准中保证这一点的部分。甚至字节模式也是POSIX扩展。不,C标准既定义了文本模式(这是实现定义的,您不能依靠它做任何有用的事情),也定义了二进制模式(这是字节可寻址的,并且每次调用
fputc
(定义了所有其他写函数)都会产生一个字节(
char
))正在写入并按1)调整文件位置。请参见7.19.2第3段和7.19.9.2第3段。恐怕这是语言的一个相当黑暗的角落。人们往往在被它咬伤之前不知道它在那里。接得好!值得注意的是,POSIX要求实现不以不同方式对待它们。