使用指针编写和读取(fwrite - fread)结构

时间:2011-12-22 09:28:55

标签: c fwrite structure fread

我正在研究邮箱项目,我有这两种结构:

struct mmbox_mail

struct mmbox_mail {
  char *sender, *recipient; 
  char *obj, *date;
  char flags; 
  size_t size; 
};

mail_t

typedef struct{
  struct mmbox_mail info;
  void *body;
  void *next;
} mail_t;

我无法修改结构的字段,因为我需要可变数据(为此我使用char *而不是char [])。

每个mail_t结构都是邮件。我需要将用户的每个邮件保存在一个文件中,可以是二进制文件或文本文件(但我认为使用二进制文件会更好,因为我的void*主体难以用纯文本保存。

我试图这样做,但似乎它不起作用:

while(mailtmp != NULL){
  fwrite(mailtmp, sizeof(mail_t), 1, fp);

  /* next mail */
  mailtmp=mailtmp->next;
}
while(mailtmp != NULL){  /* i have a list of mails and i use a mailtmp pointer to save each mail */
你可以帮帮我吗?我试图到处寻找,但我从未找到过要求保存两个结构的人,一个在另一个内部。

3 个答案:

答案 0 :(得分:3)

当然,这不会像字符串那样复制指针的大小(通常是4个字节)。我在这里看到3个选项:

  1. 序列化数据,二进制文件(http://en.wikipedia.org/wiki/Serialization)。
  2. 创建一种格式以在文本文件中存储数据。
  3. 使用XML / JSON等标记语言。
  4. 在任何情况下,您都需要遍历结构的每个字段才能将其写入数据文件。至于阅读,在前两种情况下,您必须按照编写数据的顺序进行完全阅读,在第三种情况下,您将能够以任何顺序独立阅读字段。

    如果您选择第一个方法,对于每个字符串(char *)字段,还要写入零终止字节,以便在读取它时始终知道它的结束位置。

答案 1 :(得分:0)

你正在做的是将mail_t的文字二进制表示保存到文本文件中,这只是一堆指针。您想要做的是:

fprintf( fp, "To: %s\nFrom: %s\n....\nContents: %*s\n\n", mailtmp->info.recipient, mailtmp->info.sender, mailtmp->info.size, mailtmp->body );

这将呈现指向字符串的值并将其保存到文件中。在应用程序关闭后,指向应用程序所占内存位置的指针对大多数人来说有点无用;)

编辑:“你能帮助我吗?我试图到处寻找,但我从未找到过要求保存两个结构的人,一个在另一个内部。”

如果您只拥有一流的数据类型,例如整数或浮点数等,那么您的方法就可以完美运行。但是,由于您使用的是第二类类型,即char和void数组,因此必须实际指定应如何保存指向的数据。

答案 2 :(得分:0)

好吧,你将struct的指针存储到file.not而不是它指向的数据。甚至你存储你想要的结构。很难从文件中获取它。我认为你需要一个像google protocal buffer这样的序列化组件。然后你可以编写一个适配器,将结构转换为probuf对象,然后将它存储到file.when你想要的,反过来。希望它会帮助你:)