fwrite()
被声明为下面这样。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
但实际写入的字节数只是size * nmemb。那么为什么不直接指定字节数呢?为什么需要同时指定size和nmemb?谢谢。
我认为这取决于机器的字节序。 fwrite()
写入 size * nmemb
字节。也就是说,调用以下两个函数会得到相同的结果。
fwrite(ptr, 2, 10, buf);
fwrite(ptr, 10,2, buf);
然而,棘手的问题在于以下调用:fwrite(ptr, 1, 1, buf);
会将字节写入最低内存地址。也就是说,在大端机器上它是最高有效字节,否则它是最低有效字节。
没有真正的原因。
函数被定义成这样,只是因为它是这样的;更具体地说,在出现错误时,如果没有写入所有元素,则无法保证未写入任何部分元素或文件指针位于任何特定位置。
我通常只传递元素大小为1,并在count
参数中自己进行计算。
https://chromium.googlesource.com/chromiumos/third_party/glibc/+/cvs/libc-970216/stdio/fwrite.c
正如您在不同的fwrite实现中所看到的(不仅仅是上面的链接),返回的答案是return (size_t) written / size;
。因此,在成功时,您将获得nmemb
的返回值。
例如:
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
int main() {
int num = 2;
uint64_t *arr = malloc(num * sizeof(uint64_t));
arr[0] = (uint64_t)'a' ^ (uint64_t)'b' << 8 ^ (uint64_t)'c' << 16;
arr[1] = (uint64_t)'d' ^ (uint64_t)'e' << 8 ^ (uint64_t)'f' << 16;
size_t writed_size = 0;
writed_size = fwrite(arr, sizeof(arr), num, stdout);
if (writed_size == num) {
printf(" : Success\n");
}
writed_size = fwrite(arr, 1, sizeof(arr) * num, stdout);
if (writed_size == sizeof(arr) * num) {
printf(" : Success\n");
}
writed_size = fwrite(arr, sizeof(arr) * num, 1, stdout);
if (writed_size == 1) {
printf(" : Success\n");
}
free(arr);
return 0;
}
感谢 @Eric Postpischil 更正我的先前答案。
fputc
函数size
次,按顺序从正好覆盖对象的unsigned char
数组中取值。流的文件位置指示器(如果定义)将按成功写入的字符数向前移动。如果发生错误,则流的文件位置指示器的结果值是不确定的。” - Eric Postpischilsizeof(arr)
来指定要写入的对象的大小,而 sizeof(arr)
是一个指向 uint64_t *
的指针的大小,但要写入的对象是用 sizeof(uint64_t)
分配的字节,这可能是不同的。我们也不知道字符将被写入的顺序,因为它们被组合成一个 uint64_t
进行算术运算,并且一个 uint64_t
可以用小端或大端表示。 - Eric Postpischil
fwrite
返回成功写入的整个对象的数量。虽然这似乎并不重要,但可以很容易地从写入的字节数计算出来。 - Eric Postpischilfwrite(const void *ptr, int size, int nmemb, FILE *stream)
,这将允许一次写入超过64K。或许他们想要更高级一些的东西。在我看来,今天拥有这两个参数并没有太多好处。 - Jabberwocky