如果我将二进制文件输入到数组buf,为什么我必须通过(void *)输入? 为什么我必须写(void *)?请遵守此代码,并请向我解释此代码。 (我只是从我的书中复制这段代码)
int main(void) {
FILE * src = fopen("a.png", "rb");
FILE * des = fopen("b.png", "wb");
char buf[20];
int readCnt;
if (src == NULL || des == NULL) {
puts("File open failed");
return -1;
}
while (1) {
readCnt = fread((void*)buf, 1, sizeof(buf), src);
if (readCnt < sizeof(buf)) {
if (feof(src) != 0) {
fwrite((void*)buf, 1, readCnt, des);
puts("File copy complete");
break;
}
else
puts("File copy Failed");
break;
}
fwrite((void*)buf, 1, sizeof(buf), des);
}
fclose(src);
fclose(des);
return 0;
}
答案 0 :(得分:2)
因为fread()
&amp; fwrite()
是泛型函数,用于读取和写入irrespective
文件data type
中的二进制数据。
fwrite()的手册页说,
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
什么是第一个论点,它的const void *ptr
意味着它的期待地址。它可以是任何变量地址int或char或任何其他数据类型。
答案 1 :(得分:0)
转换为void*
是因为这是函数所期望的。请参阅here和here。
您的代码将在没有此强制转换的情况下进行编译,因为不需要转换为void*
(请参阅下面的引用),但我想作者希望尽可能准确。
6.3.2.3指针
1指向void的指针可以转换为指向任何不完整或对象类型的指针。指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回;结果应该等于原始指针。
另一件事 - (void*)
是抑制编译器警告的好方法。开始时可能不是一件好事(警告是有原因的),但如果需要,这是一种忽略函数参数中错误指针类型的简单方法。
答案 2 :(得分:0)
这样您就可以传递任何指针类型。例如,如果你想编写一个类似于
的结构struct point {
int x;
int y;
};
struct point my_point = {1, 2};
FILE *file = fopen("sample-file.bin", "w");
if (file != NULL) {
// Normally check that this returns the number of
// written items
fwrite(&my_point, 1, sizeof(my_point), file);
fclose(file);
}
会起作用,当您打开文件进行阅读时,您也可以fread(&my_point ...)
。
请注意,在c中不需要转换为void *
,也不需要从void *
转换为其他指针类型,例如
char *example = malloc(size + 1);
完全有效,malloc()
返回void *
。
答案 3 :(得分:0)
这应该是一个评论,但我没有这个名声。在您的代码中:
if (src == NULL || des == NULL) { puts("File open failed"); return -1; }
有可能src或des可能已正确打开,因此应该fclose();
调用它。
类似的东西:
if (src == NULL || des == NULL)
{
if(src)
{
fclose(src);
}
if(des)
{
fclose(des);
}
puts("File open failed");
return -1;
}
会更好。