我需要编写一个将“n”元素数组写入二进制输出文件的函数。我想避免为我可能希望编写的每种类型的数据(int,float,double等)编写单独的函数。
有没有什么方法可以指定数据类型(可能是字节数)作为函数的参数,让函数确定它如何处理它?
e.g。
f_writebinary(??? *data, int size, long n) {
for(i=0;i<n;i++) {
fwrite((data+i),size,1,stdout);
}
}
...或者这对C来说是完全荒谬的事情吗?
答案 0 :(得分:2)
是的,这正是fwrite()
的确切含义。它使用const void *
表示&#34;指向任何类型的数据&#34;,并将其视为指向字节的指针。
因此,您的包装器并不是真的需要,您可以立即对fwrite()
进行正确大小的调用来编写数组:
const int my_ints[3] = { 1, 2, 3 };
const double my_doubles[5] = { 5, 4, 3, 2, 1 };
fwrite(my_ints, sizeof *my_ints, sizeof my_ints / sizeof *my_ints, stdout);
fwrite(my_doubles, sizeof *my_doubles, sizeof my_doubles / sizeof *my_doubles, stdout);
请注意,将二进制数据写入stdout
可能有点粗鲁,并且还应检查I / O调用是否有错误。
如果删除y字节的&#34; x元素&#34; fwrite()
的API使用的模型,只需将它们视为单个字节块,您可以简化调用:
fwrite(my_ints, sizeof my_ints, 1, stdout);
fwrite(my_doubles, sizeof my_doubles, 1, stdout);
请注意,循环中没有任何意义,每个数组中的数字将在内存中相邻,因此fwrite()
可以一次性写入所有数字。通常最好尽可能地减少I / O调用的数量,因此如果您只能写n * m
个字节而不是n
m
次写入{{1}}每个字节,这通常更好。请记住,您编写的许多底层设备都是面向块的,并且无论如何都会从获取整个数据块中获益很多,因为这是他们必须编写的内容。
答案 1 :(得分:1)
只需将???
替换为char
即可。或者在函数内部使用void
并强制转换为char*
,因此在调用函数时无需强制转换为char*
。最好使用size_t
代替int
和long
:
#include <stdio.h>
...
size_t f_writebinary(void * data, size_t size, size_t n)
{
size_t result = 0;
for (size_t i = 0; i < n; ++i)
{
size_t result_inner = fwrite(((char *) data) + (i * size), size, 1, stdout);
if (!result_inner)
{
/* handle error here */
}
else
{
++result;
}
}
return result;
}
优化版本:
size_t f_writebinary(void * data, size_t size, size_t n)
{
size_t result = 0;
n *= size;
for (size_t i = 0; i < n; i += size)
{
size_t result_inner = fwrite(((char *) data) + i, size, 1, stdout);
if (!result_inner)
{
/* handle error here */
}
else
{
++result;
}
}
return result;
}
简短地说:只需模仿签名fwrite()
使用。