在我的程序中,我从键盘接收输入。我将该输入放在struct
中,其中包含两个char
字段和一个int
字段。如何仅使用函数写入整个struct
?
我不想要分别写入struct
的每个成员。
答案 0 :(得分:4)
C没有"指令"。
您应该能够使用单个函数调用,例如:
fwrite(&mystructure, sizeof mystructure, 1, myfile);
但这并非没有缺点:
答案 1 :(得分:1)
这取决于您struct
的定义方式,是否希望您的输出是人类可读的,以及输出文件是否要在不同的架构上读取。
其他人提供的fwrite
解决方案会将结构的二进制表示写入输出文件。例如,给出以下代码:
#include <stdio.h>
int main(void)
{
struct foo {
int x;
char name1[10];
char name2[10];
} items[] = {{1,"one","ONE"}, {2,"two","TWO"}};
FILE *output = fopen("binio.dat", "w");
fwrite( items, sizeof items, 1, output );
fclose( output );
return 0;
}
如果我向控制台显示binio.dat
的内容,我会得到以下内容:
john@marvin:~/Development/Prototypes/C/binio$ cat binio.dat oneONEtwoTWOjohn@marvin:~/Development/Prototypes/C/binio$ john@marvin:~/Development/Prototypes/C/binio$ od -c binio.dat 0000000 001 \0 \0 \0 o n e \0 \0 \0 \0 \0 \0 \0 O N 0000020 E \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000040 \0 \0 \0 \0 002 \0 \0 \0 t w o \0 \0 \0 \0 \0 0000060 \0 \0 T W O \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000100 \0 \0 \0 \0 \0 \0 \0 \0 0000110
整数值显示为垃圾(以上未再现),因为它们已被存储为字节序列01,00,00,00和02,00,00,00(x86是little-endian),它们是不可打印的字符。另请注意,name1
的所有10个字符和name2
的所有20个字符都会写入文件,这可能是您想要的,也可能不是。
如果你的struct包含指针,情况会变得更加复杂,因为存储到文件中的是指针值,而不是指向的东西:
#include <stdio.h>
int main(void)
{
struct foo {
int x;
char *name1;
char *name2;
} items[] = {{1,"one","ONE"}, {2,"two","TWO"}};
FILE *output = fopen("binio.dat", "w");
fwrite( items, sizeof items, 1, output );
fclose( output );
return 0;
}
这次我
john@marvin:~/Development/Prototypes/C/binio$ cat binio.dat ��������john@marvin:~/Development/Prototypes/C/binio$ john@marvin:~/Development/Prototypes/C/binio$ od -c binio.dat 0000000 001 \0 \0 \0 260 205 004 \b 264 205 004 \b 002 \0 \0 \0 0000020 270 205 004 \b 274 205 004 \b 0000030
请注意,文件中根本没有出现任何字符串;如果您使用其他程序读取此文件,它将看到(很可能)无效地址。
如果您希望输出是人类可读的和,您希望能够在不同的架构上读取这些值,那么您几乎必须使用格式化输出,这意味着您必须编写每个成员分开:
#include <stdio.h>
int main(void)
{
struct foo {
int x;
char *name1;
char *name2;
} items[] = {{1,"one","ONE"}, {2,"two","TWO"}};
FILE *output = fopen("binio.dat", "w");
int i;
for (i = 0; i < sizeof items / sizeof items[0]; i++)
{
fprintf(output, "%d %s %s\n", items[i].x, items[i].name1, items[i].name2);
}
fclose( output );
return 0;
}
john@marvin:~/Development/Prototypes/C/binio$ cat binio.dat 1 one ONE 2 two TWO
你当然可以将这个操作包装在你自己的函数中,比如
int printFoo( FILE *output, const struct foo item )
{
return fprintf( output, "%d %s %s\n", item.x, item.name1, item.name2);
}
但最终,这就像它变得一样简单。
如果您不关心可读性和可移植性,fwrite
解决方案很有用,但如果您在结构中有任何指针成员,则仍需要小心。