我试图在多个地方查看,我无法理解为什么fwrite不起作用。
如果我有100个字段的结构,我不想使用带有100个格式说明符的fprintf。
struct emp
{
char name[15];
int age;
int salary;
char address[30];
};
int main()
{
char str[60];
struct emp emp1[5] = {{"Yoda",23,45000,"Asia"},{"Darth",34,2344,"NAmerica"},{"Jabba",22,5566,"Africa"},{"Luke",33,3399,"SAmerica"},{"Laya",44,6677,"Europe"}};
FILE *fp;
fp = fopen("C:/.../sampleText.txt","w");`
int i=0;
for(i=0; i<5; i++)
{
fwrite(&emp1[i],sizeof(emp1[i]),1,fp);
//fprintf(fp,"%s, %d, %d, %s\n",&emp1[i].name,emp1[i].age,emp1[i].salary,emp1[i].address);
}
fclose(fp);
getch();
}
答案 0 :(得分:3)
有两个答案:
在你的示例结构中,你没有指针,所以你可以逐字地将结构写入文件,然后在同一个(类型)机器上运行的程序的另一个调用中,你可以读回来,并且你会看到相同的数据。
但是,如果您的结构包含指针,则无法将结构写入磁盘。程序的一次调用中的指针在程序的另一次调用中不需要具有任何意义。如果您需要在little-endian(Intel)和big-endian(PowerPC,SPARC)机器之间移植数据,则必须使用与平台无关的方式来访问数据;简单地将数据写入磁盘是行不通的。
因此,在可移植性不成问题的情况下,此代码应该可用 - Unix或Windows。它使用"wb"
的{{1}}和"rb"
参数,因为数据是二进制数据,而不是纯文本。 fopen()
是可选的,但在Unix上无害;它在Windows上至关重要。该代码还将文件名修复为b
,以便可以在任一平台上运行,写入当前目录。它写入数据;然后它读取数据;然后它将读取的数据与写入的数据进行比较,报告任何问题。如果程序没有说什么,一切都没问题。
sampledata.bin
文件#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct emp
{
char name[15];
int age;
int salary;
char address[30];
};
int main(void)
{
char const filename[] = "sampledata.bin";
struct emp emp1[5] =
{
{ "Yoda", 23, 45000, "Asia" },
{ "Darth", 34, 2344, "N America" },
{ "Jabba", 22, 5566, "Africa" },
{ "Luke", 33, 3399, "S America" },
{ "Leia", 44, 6677, "Europe" },
};
struct emp emp2[5];
FILE *ifp;
FILE *ofp;
int i;
ofp = fopen(filename, "wb");
if (ofp != 0)
{
if (fwrite(emp1, sizeof(emp1), 1, ofp) != 1)
{
fprintf(stderr, "Failed to write to %s\n", filename);
exit(1);
}
fclose(ofp);
}
ifp = fopen(filename, "rb");
if (ifp != 0)
{
if (fread(emp2, sizeof(emp2), 1, ifp) != 1)
{
fprintf(stderr, "Failed to read from %s\n", filename);
exit(1);
}
fclose(ifp);
}
for (i = 0; i < 5; i++)
{
if (emp1[i].age != emp2[i].age ||
emp1[i].salary != emp2[i].salary ||
strcmp(emp1[i].name, emp2[i].name) != 0 ||
strcmp(emp1[i].address, emp2[i].address) != 0)
printf("Difference in record %d\n", i);
}
return 0;
}
的内容:
sampledata.bin
答案 1 :(得分:2)
您没有指定fwrite doesn't work
的含义,但我会假设您正在使用Windows,在这种情况下,您需要指定"wb"
到fopen
。默认情况下,在Windows上,它写在text mode
(即"wt"
)。
答案 2 :(得分:1)
将struct
写入文件或套接字并不是一个好主意。解决问题很复杂。最好的方法是在写入之前使用序列化。另外,正如Jim上面指出的那样,请确保以二进制文件打开文件。
看看这个问题和答案。你的问题有一个很好的答案和解释。 Passing a structure through Sockets in C
答案 3 :(得分:0)
数据序列化是一项非常重要的任务。正如其他人指出的那样,在某些情况下,可以将结构的内容作为二进制数据写入磁盘。这是最简单的写法,但它不太可能稳定。每次重新编译代码时,都可能会改变写入和读入数据的格式。
您最好的选择是使用标准数据交换格式,例如CSV,XML或JSON。有许多现有工具可以使用这些格式,因此您应该考虑使用其中一种格式。