2011-12-22 76 views
2

我的工作邮箱项目结构,我有这两种结构:写入和读取(fwrite的 - FREAD)与指针

结构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 */ 

你能帮助我,我试着到处寻找,但我从来没有发现有人问,以节省二号呢?结构,一个在另一个内。

回答

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

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

编辑:“你能帮我吗?我试图到处搜索,但我从未找到要求保存的人两个结构,一个在另一个里面。“

如果你只有第一类的数据类型,如int或float等,你的方法将完美工作。但是,由于您使用的是第二类类型,即char和void数组,您必须实际指定应如何保存指向的数据。

+0

我试过这种方法,但我发现一个问题是:如何在纯文本中保存void * body?我的意思是,电子邮件的正文可能是各种数据,所以我不能将它保存为纯文本。 O.o – user1111399 2011-12-22 09:47:51

+0

那么电子邮件格式本质上是明文的。连接到电子邮件的二进制文件是base64'd,允许通过明文协议传输。你可以编写一个解析器来从电子邮件中提取实际的文本;你可以解析出这些文件,解开它们,并将它们写入文件;你可以做任何你想做的事。然而,你的问题的范围并不包括这一点,完全取决于你决定如何去做这件事。 – Kaslai 2011-12-22 10:16:48

+0

对不起,但我是一个“自制”项目,我想在本地运行,而不是远程..所以我正在寻找一些不太复杂的东西:)在未来,我将实现功能,使其远程运行,但此刻我想让它在本地工作.. :)无论如何,谢谢! :D – user1111399 2011-12-22 14:17:09

3

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

  1. 序列化数据,二进制文件(http://en.wikipedia.org/wiki/Serialization)。
  2. 创建格式以将数据存储在文本文件中。
  3. 使用的标记语言,如XML/JSON等

在任何情况下,你需要通过结构的各个领域,以将其写入数据文件。至于阅读,在前两种情况下,您必须完全按照您写入数据的顺序进行阅读,在第三种情况下,您可以按任意顺序独立阅读字段。

如果你选择第一种方法,对于每一个字符串(字符*)字段写入也是零终止字节,这样你总是知道在哪里读它时,后端。

+0

好吧,我不能使用XML/JSON,ecc ..因为我不知道:(我试图创建一个格式来存储数据(如保存发件人,然后保存收件人,然后保存数据,ECC ... ),但它似乎不是很有效率..(任何建议被接受.. :))顺便说一句,我会寻找序列化.. :) – user1111399 2011-12-22 09:55:12

+0

序列化数据的想法是,你写的部分完全在与您阅读的顺序相同。所以,e。 G。如果您需要存储具有名称,年龄,地址的客户,则可以打开文件,而不打开EOF:写入名称(具有零终止字节),写入时间(整数,4个字节),写入地址(具有零终止字节) 。读取将是:打开文件,而不是EOF:读取字符,直到零字符到缓冲区(名称),读取4字节(年龄),读取字符,直到零字符到缓冲区(地址)。 – dimir 2011-12-22 10:08:22

+0

好的。我知道了。今天,我再次写这个程序,我保持联系。 :d(我的英语不好真的很抱歉.. :()非常感谢!d这里系列化可能性 – user1111399 2011-12-22 13:33:16

0

好,你是存储结构的指针到file.not数据点吧to.even您存储结构,你want.it难以从文件中得到它。我认为你需要一个序列化组件,如google protocal buffer。那么你可以写一个适配器,转换结构来probuf对象,然后存储它file.when你想,RETR it.hoping它会帮助你:)

+0

真的很感谢您的帮助!d但是,我想我已经与dimir的回答解决了..我说“我想“因为我不确定.. – user1111399 2011-12-22 13:44:47