5

我需要为我正在上的一门课做作业。这是一个简单的 C 语言电话簿应用程序,我在使用它时遇到了一些麻烦,因为我需要在程序中使用一些新东西,而且截止日期非常紧迫。

我环顾四周,找到了一些答案,但每次都有新的答案出现。:)

这是我的(简化的)程序:

typedef struct record
{
    char fname[31];
    char lname[31];
    char tel[21];
    struct record *next;
} record;


record *new_entry(record *first, char *fname, char *lname, char *tel)
{
    record *new;
    new=(record*) malloc(sizeof(record));
    strcpy(new->fname, fname);
    strcpy(new->lname, lname);
    strcpy(new->tel, tel);
    new->next=first;
}


void fileopen (char *db_file)
{
    FILE *fp;  

    fp=fopen(db_file, "rb");
    if (fp==NULL) 
    {
        fp=fopen(db_file, "wb");
        fclose(fp);
        fp=fopen(db_file, "r+b");
    }
}



int main
{
 char db[51];
 record *next = NULL;

 printf("File:           "); scanf("%s, db);
 fileopen(db);
 printf("First name:     "); scanf("%s", fname);
 printf("Last name:      "); scanf("%s", lname);
 printf("Phone number:   "); scanf("%s", tel);
 first=new_entry(*first, fname, lname, tel);
}

我省略了不必要的部分。现在知道不多了,但是班长说我应该用二进制文件来存储和恢复数据。但是如果我应该如何使用 fread 和 fwrite,我真的很困惑。


非常感谢您的解决方案!我想我开始理解这个概念了。该程序现在存储数据(至少我认为是这样,因为随着我添加更多数据,文件会不断增长。)当启动一个新的二进制文件时,程序会在请求时正确显示数据,但如果我关闭它并重新打开同一个文件,当它试图列出联系人时没有任何反应。

这是(再次简化,我在实际作业中的一条记录中有 10 个详细信息)打开功能:

record *open (char *db_file, record start)
{
  FILE *fp
  record *temp = start;
  fp=fopen(db_file, "rb");
  while (fread(temp, sizeof(rekord), 1, fp)>0) 
    {
        fread(temp->fname, sizeof temp->fname, 1, fp);
        fread(temp->lname, sizeof temp->lname, 1, fp);
        fread(temp->tel, sizeof temp->tel, 1, fp);
    temp=temp->next;
    }
  fclose(fp);
  return temp;
}

在 main() 中,我使用:

start=open(db, start);

声明部分:

record *start=NULL;

如果有人回复,再次感谢。

4

3 回答 3

4

要将链接列表写入文件,您可以遍历列表并编写结构。

#include <stdio.h>

record *it = first;

while (it != NULL) {
    fwrite (it->fname, sizeof it->name, 1, stream);
    fwrite (it->lname, sizeof it->lname, 1, stream);
    fwrite (it->tel, sizeof it->tel, 1, stream);
    it = it->next;
}

stream是一个文件,您可以wbfopen.

于 2012-11-11T11:03:23.300 回答
1

所以,希望这个任务能解释为什么手动序列化/反序列化是一个糟糕的想法(在行业中,做这种事情的真正方法是通过自动代码生成,例如协议缓冲区),但是为了这个任务的目的,您将需要写入链表的内容而不写入链接,然后在反序列化时需要重建链接,因为简单地写入和读取列表中下一个指针的地址是不正确的.

于 2012-11-11T11:01:05.730 回答
1

将除 *next 指针之外的所有内容写入文件,然后按顺序将它们读回。

void write_book(const record *start) {
   FILE *f;
   record end;
   memset(end,0,sizeof(struct record));
   f = fopen("foo","wb");
   for(;start != NULL; start = start->next) { 
     fwrite(start->fname, 31, 1, F);
     fwrite(start->lname, 31, 1, F);
     fwrite(start->tel, 21, 1, F);
     fwrite(end->next, sizeof(void*), 1, F);
   }
   memset(end,0,sizeof(struct record));
   fwrite(end, sizeof(struct record),1,F);
   fclose(f);
}

读取时,将数据读出,直到命中空记录。您可以为此使用 fread() 。只要记住分配新记录,用 fread() 读取它并更新下一个指针。

于 2012-11-11T11:02:22.717 回答