我有一个结构:
typedef struct student {
char *name;
char *surname;
int age;
} Student;
我需要将其写入二进制文件。
Student *s = malloc(sizeof(*s));
我用数据填充我的结构,然后我写入文件:
fwrite(s, sizeof(*s), 1, fp);
在我的文件中不存在名称和姓氏,它有char *的地址。 我怎样才能写一个单词而不是一个地址?
答案 0 :(得分:10)
您需要取消引用指针并编写结构的各个部分。 (你不应该直接编写一个结构,而是编码它的部分并编写它们:
Student *s = malloc(sizeof(*s));
s->name = "Jon";
s->surname = "Skeet";
s->age = 34;
// ....
fwrite(s->name, sizeof(char), strlen(s->name) + 1, fp);
fwrite(s->surname, sizeof(char), strlen(s->surname) + 1, fp);
//This one is a bit dangerous, but you get the idea.
fwrite(&(s->age), sizeof(s->age), 1, fp);
答案 1 :(得分:4)
你必须做一些额外的工作来写出结构元素指向的数据 - 可能只是逐个元素地写出来。
或者将您的结构更改为以下内容:
typedef struct
{
char name[MAX_NAME_LEN];
char surname[MAX_SURNAME_LEN];
int age;
} Student;
答案 2 :(得分:3)
如果您想直接将结构写入文件,您需要定义名称和姓氏的大小,而不是动态分配它。
typedef structure student { char name[100]; char surname[100]; int age; }
否则你需要逐个在结构中写下每个信息。
答案 3 :(得分:3)
在C中,您必须手动序列化结构(将它们转换为一系列字节)。如果您希望输出的数据可被其他计算机读取,则必须使用字节顺序帐户endianness。
这是一个序列化结构(将其写入文件)的简单示例,忽略字节序/不同的字大小并使代码不可移植:
size_t length;
length = strlen(s->name) + 1;
fwrite(&length, sizeof(length), 1, fp);
fwrite(s->name, 1, length, fp);
length = strlen(s->surname) + 1;
fwrite(&length, sizeof(length), 1, fp);
fwrite(s->surname, 1, length, fp);
fwrite(&s->age, sizeof(s->age), 1, fp);
要反序列化:
size_t length;
fread(&length, sizeof(length), 1, fp);
s->name = malloc(length);
fread(s->name, 1, length, fp);
fread(&length, sizeof(length), 1, fp);
s->surname = malloc(length);
fread(s->surname, 1, length, fp);
fread(&s->age, sizeof(s->age), 1, fp);
在实际应用中,您应该检查输入的有效性,而不是盲目地假设输入有效且值得信赖。此外,您需要确定用于存储int
,size_t
等的字节顺序,并确保使用位移以正确的字节顺序读/写它们。
顺便说一句,您可能需要查看tpl,一个简单的C二进制序列化库。
答案 4 :(得分:0)
您需要取消引用s
并单独写出结构的每个元素,以实际将内容写入文件:
size_t nameCount = strlen(s->name) + 1;
fwrite(s->name, sizeof(char), nameCount, fp);
size_t surnameCount = strlen(s->surname) + 1;
fwrite(s->surname, sizeof(char), surnameCount, fp);
答案 5 :(得分:0)
请注意,无论如何,您将无法以“普通”形式查看字段,因为您将其写入二进制文件。尝试在fopen的模式参数中打开没有“b”的文件(r + \ w \ a等而不是rb + \ wb \ ab)。
你可以看到,当使用fread时(从二进制文件中,在“rb”模式下打开后,你应该得到预期的结构字段。
答案 6 :(得分:0)
你必须像其他人所说的那样单独写出字段。有助于回读数据的一件事是在每个条目之前写出字符串长度,例如
size_t len;
len = strlen(s->name)+1;
fwrite(&len,sizeof(len),1,stream);
fwrite(s->name,sizeof(*(s->name)),len,stream);
...
回读是
的问题Student * s = malloc(sizeof(*s));
size_t len;
fread(&len,sizeof(len),1,stream);
s->name = malloc(len);
fread(s->name,sizeof(*(s->name)),len,stream);
...