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 をどのように使用すればよいのか、本当に混乱しました。


解決策をどうもありがとう!概念を理解し始めていると思います。プログラムはデータを保存するようになりました(少なくとも、データを追加するとファイルが大きくなり続けるため、保存されていると思います)。新しいバイナリファイルを開始すると、プログラムは要求されたときにデータを正しく表示しますが、それを閉じて再度開くと連絡先を一覧表示しようとしても何も起こりません。

これが(再び単純化された、実際の割り当ての1つのレコードに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;
}

streamwbモードで開くことができるファイルですfopen

于 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 に答える