在C中写入指向文件的指针

时间:2010-05-04 07:08:01

标签: c file pointers

我有一个结构:

typedef struct student {
  char *name;
  char *surname;
  int age;
} Student;

我需要将其写入二进制文件。

Student *s = malloc(sizeof(*s));

我用数据填充我的结构,然后我写入文件:

fwrite(s, sizeof(*s), 1, fp);

在我的文件中不存在名称和姓氏,它有char *的地址。 我怎样才能写一个单词而不是一个地址?

7 个答案:

答案 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);

在实际应用中,您应该检查输入的有效性,而不是盲目地假设输入有效且值得信赖。此外,您需要确定用于存储intsize_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);
...