在我的程序中,我从键盘接收输入。我将该输入放在struct
包含两个char
字段和 1 个int
字段的 a 中。如何struct
仅使用一个函数写入整个内容?
我不想单独写给每个成员struct
。
在我的程序中,我从键盘接收输入。我将该输入放在struct
包含两个char
字段和 1 个int
字段的 a 中。如何struct
仅使用一个函数写入整个内容?
我不想单独写给每个成员struct
。
C没有“指令”。
您应该能够使用单个函数调用,例如:
fwrite(&mystructure, sizeof mystructure, 1, myfile);
但这并非没有缺点:
这取决于您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 一 \0 \0 \0 \0 \0 \0 \0 开 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 二\0 \0 \0 \0 \0 0000060 \0 \0 二 \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),它们不是可打印字符. 另请注意,所有 10 个字符name1
和所有 20 个字符name2
都写入文件,这可能是您想要的,也可能不是。
如果您的结构包含指针,情况会变得更加复杂,因为存储到文件中的是指针值,而不是指向的内容:
#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 一一一 2 二 二
您当然可以将该操作包装在您自己的函数中,例如
int printFoo( FILE *output, const struct foo item )
{
return fprintf( output, "%d %s %s\n", item.x, item.name1, item.name2);
}
但最后,这很简单。
如果您不关心可读性和可移植性,该fwrite
解决方案效果很好,但如果结构中有任何指针成员,您仍然必须小心。