双方向リストへのデータ登録

このQ&Aのポイント
  • C言語を使って双方向リストへのデータ登録で問題が発生しています。
  • ファイルからのデータ読み込みは成功しているが、新しいデータの登録がうまくいかない。
  • データ登録の際に名前の入力に「gets」を使用しているが、次のif文が効かない。
回答を見る
  • ベストアンサー

双方向リストへのデータ登録

C言語の勉強をしております。 双方向リストへのデータの登録でうまくいかず詰まってしまいました。 <ヘッダファイル> // 構造体 typedef struct address { char names[32]; /* 名前 */ char tels[32]; /* 電話番号 */ struct address *prev; /* 前へのポインタ */ struct address *next; /* 次へのポインタ */ }Address; extern Address *top_pt; extern Address *work_pt; extern Address *w_pt; extern Address *inAdd; // ファイルからの読み込み top_pt = NULL; while(!feof(fp)) { work_pt = (Address *)malloc(sizeof(Address)); if(!work_pt){ printf("メモリ不足"); exit(1); } fscanf(fp, "%s %s", work_pt->tels, work_pt->names); work_pt->next = top_pt; top_pt = work_pt; work_pt->prev = top_pt; /* カウンタを用意して、実際のデータ件数をカウントしておく */ ++trueCount; } これで、双方向リストへファイルの内容を格納することは出来ました。 次に、構造体へデータを新規登録したいのですが、構造体を共有している別ソースファイルにて、 for(i=0; 1000>trueCount+i; i++){ inAdd = (Address *)malloc(sizeof(Address)); if(!inAdd){ printf("メモリ不足"); exit(1); } printf("登録する名前を入力してください:"); gets(inAdd->names); /* 名前が未入力でEnterされた場合 */ if(!*inAdd->names){ /* ループを抜け、トップメニューへ */ flag = 1; break; } printf("電話番号を入力してください:"); scanf("%s", inAdd->tels); /* 読み込んだ構造体へデータを追加する */ work_pt->next = inAdd; inAdd->prev = work_pt; inAdd->next = NULL; } として、構造体の中身を表示させたところ、 ファイルの最終データと、入力したデータのみになってしまいました。 なぜなのか分かりません・・・。 有識者の方でこの下手なソースを読んで指南していただける方はおられますでしょうか? また、データ登録の際に名前の入力に「gets」を使用しているんですが、 「scanf」だとその次のif文が効かないみたいで少し困っています。 (出来ればANSIC標準のscanfを使いたい) 以上、よろしくお願いいたします。

  • ya-cha
  • お礼率68% (184/268)

質問者が選んだベストアンサー

  • ベストアンサー
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.9

アドバイスの続きです。 >>●本当は、どのような動作を期待していましたか? >ファイルから読み込んだデータに、入力したデータが追加されていくイメージです。 > データの入力を > top_pt->next = inAdd; > inAdd->prev = top_pt; > inAdd->next = NULL; > のようにしてもうまくいかなかったんですが、これもおかしいでしょうか? ・リストの先頭に要素を追加するなら、 inAdd->next = top_pt; /* 入力データのnextに今の先頭要素をリンク。 */ inAdd->prev = NULL; /* 入力データのprevにNULLを代入 */ top_pt->prev = inAdd; /* 先頭要素のprevに入力データをリンク。 */ top_pt = inAdd; /* 入力データを先頭要素とする */ で良いと思います。 ・リストの末尾に要素を追加したい場合、 top_pt以外に、bottom_pt等を用意して、最終要素も管理してあげると良いのでは、 ないでしょうか。 ・蛇足 アルゴリズムが理解できたら、次はもう一歩発展させて、要素に追加する処理を 関数化してみてはどうでしょう。 例えば、 /** * 双方向リストの先頭にアイテムを追加する。 * * @param[in] pItem 追加する要素 */ int insertItemToTop(Address *pItem) { [づらづら] } ・蛇足その2 > また、ファイルの末尾のチェック方法についてですが、ループの途中に、fscanfとEOFを比較して、ループから抜けるようにしました。 > > ごみデータが入ってしまう事は私も分かっており、悩んでいたんですが、回答者様のご指摘を参考に上記処理にて解決できました。(正しい方法なのかは分かりませんが・・・) ファイル読込にも、fgets() + sscanf()の組み合わせが有効な場合もあるかもしれません。

ya-cha
質問者

お礼

アドバイスありがとうございます。 関数化について考えてみたいと思います。 また、fgetsとsscanの組み合わせの有効的な使用方法は分かりませんので、とりあえず私の分かる範囲で処理を記述してみたいと思います。 色々アドバイスありがとうございました。

その他の回答 (8)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.8

標準に含まれているかどうかは, それこそ「標準を確認する」だけでわかるはずです. ANSI そのものには当たっていませんが, ISO や JIS の規格を調べれば「gets が標準に含まれている」ことは想像できるはずです. JIS なら http://www.jisc.go.jp/ の「JIS 検索」で規格番号として「X3010」を入れれば閲覧だけは出来ます. あと, この書き方では「最後にごみデータが入る」可能性があります. 「ファイルの末尾」のチェック方法によるもので, 実際に空のファイルを読み込ませてみれば簡単にわかるはず.

ya-cha
質問者

お礼

ありがとうございます。 また、ファイルの末尾のチェック方法についてですが、ループの途中に、fscanfとEOFを比較して、ループから抜けるようにしました。 ごみデータが入ってしまう事は私も分かっており、悩んでいたんですが、回答者様のご指摘を参考に上記処理にて解決できました。(正しい方法なのかは分かりませんが・・・) ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

ああ, ついでにもう 1つですが, この 「ファイルからの読み込み」 のところは論理的にたぶん間違っています. この形で feof を使うのは危ない気がするなぁ.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

すみません, 「『scanf』はANSIC標準だけど、『gets』は違う」 という情報はどこにありますか? もちろん「gets は危険なので使うべきではない」というのはその通りだけど....

ya-cha
質問者

お礼

カーニハン/リッチーのANSIC規格準拠のプログラミング言語Cに「gets」関数が出てこないので、標準ではないのかと思っていますが、違いましたでしょうか? また、No7についてですが、理由が全く分かりません(泣) 何故なのか教えていただけないでしょうか?

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.5

●これは何をしめしていますか? extern Address *top_pt; extern Address *work_pt; extern Address *w_pt; extern Address *inAdd; #推測 extern Address *top_pt;// 双方向リストの先頭要素 extern Address *work_pt;// 処理中データをしめすワーク extern Address *w_pt;// 何?? extern Address *inAdd;// 入力中のデータ > これで、双方向リストへファイルの内容を格納することは出来ました。 双方向リストの前方に、1件づつデータを追加していくアルゴリズムみたいですね。 > /* 読み込んだ構造体へデータを追加する */ > work_pt->next = inAdd; > inAdd->prev = work_pt; > inAdd->next = NULL; この時点で work_pt はどこをさしているつもりですか? 私の予想だと work_pt は先頭要素ですね。 > work_pt->next = inAdd; で、先頭要素のnextに入力データをリンク。 > inAdd->prev = work_pt; 入力データのprevに先頭要素をリンク。 > inAdd->next = NULL; 入力データのnextにNULLを代入。 しているので、 > として、構造体の中身を表示させたところ、 > ファイルの最終データと、入力したデータのみになってしまいました。 そのとおりの結果なのではないでしょうか? ●本当は、どのような動作を期待していましたか? > また、データ登録の際に名前の入力に「gets」を使用しているんですが、 > 「scanf」だとその次のif文が効かないみたいで少し困っています。 > (出来ればANSIC標準のscanfを使いたい) 未入力でEnterが押された場合、scanfが再度入力待ちになるのは、正しい動作です。 未入力でEnterが押された場合を判定して、処理したい場合、 拙者なら、 ----------------------------------------------------------------------     char buffer[4096];          memset(buffer, 0, sizeof(buffer));     fgets(buffer, sizeof(buffer) - 1, stdin);     if (buffer[0] == '\n') {       /* ループを抜け、トップメニューへ */       flag = 1;       break;     }     sscanf(buffer, "%s", inAdd->names); ---------------------------------------------------------------------- のような処理にしてしまいますが、どうでしょう。

ya-cha
質問者

お礼

ご回答ありがとうございます。 >extern Address *w_pt;// 何?? ですが、mallocで確保したメモリの解放時に使用しているので、ここでは不必要でした。 必要の無いものまで一緒に貼り付けてしまい申し訳ございませんでした。 >●本当は、どのような動作を期待していましたか? ファイルから読み込んだデータに、入力したデータが追加されていくイメージです。 データの入力を top_pt->next = inAdd; inAdd->prev = top_pt; inAdd->next = NULL; のようにしてもうまくいかなかったんですが、これもおかしいでしょうか? >のような処理にしてしまいますが、どうでしょう。 参考にさせていただきます。 本当にありがとうございました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

> 「scanf」だとその次のif文が効かないみたいで少し困っています。 > if(!*inAdd->names){ * は、どういった意味合いで付けていますか?

ya-cha
質問者

お礼

「構造体のデータ」です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

すみません, できれば「出来れば ANSI C 標準の scanf を使いたい」の意味をお教えいただけますか? ひょっとして, 「ANSI C 標準でない scanf」もある?

ya-cha
質問者

お礼

「scanf」はANSIC標準だけど、「gets」は違うという意味で書いただけです。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

せっかくソースコードを載せるのであれば、 回答者のところで「そのまま」コピー&ペーストして コンパイル&実行できるよう、 断片でなく全体を載せる方がよいと思いませんか? 載っていない部分を想像で補うことができないのです。

ya-cha
質問者

お礼

ご回答ありがとうございます。 全体が大きかったので、必要かなと思う箇所のみ貼り付けておりました。 申し訳ございません。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

とりあえずヒントだけ。 >構造体の中身を表示させたところ、 >ファイルの最終データと、入力したデータのみになってしまいました。 >なぜなのか分かりません・・・。 ファイルの読み込みと、キー入力でリストの接続処理が違う理由は何でしょうか? 入力がファイルかキーボードかが違うだけでやることは一緒ですよ。 >また、データ登録の際に名前の入力に「gets」を使用しているんですが、 >「scanf」だとその次のif文が効かないみたいで少し困っています。 scanf()で取り込まれている内容がどうなっているのか、確認してみましょう。

ya-cha
質問者

お礼

ご回答ありがとうございます。

関連するQ&A

  • 単方向リスト

    #include<stdio.h> #include<stdlib.h> #include<string.h> struct Address{ char name[100]; char tel[100]; char email[100]; }; struct AddressList { struct Address addr; //データそのもの struct AddressList *next; //後続ノードへのポインタ struct AddressList *prev; }; struct AddressList *this,*last,*new,*first; struct Address *addr; /*--------ここからmain関数------------*/ int main(void){ int n,i; //何番目に入れるか? char quit[100]; //繰り返しを止める時に利用。 first=last=NULL; //まず初期化 addr =(struct Address *)malloc(sizeof(struct Address)); if(addr==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } while(-1){ printf("整数を入力してください。\n"); scanf("%d",&n); printf("名前を入力してください。\n"); scanf("%s",addr->name); printf("電話番号を入力してください。\n"); scanf("%s",addr->tel); printf("メールアドレスを入力してください。\n"); scanf("%s",addr->email); new =(struct AddressList *)malloc(sizeof(struct AddressList)); //新たに加えるリストの動的メモリー確保 if(new==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } new->addr=addr; //ここでエラーが発生します。 new->next=NULL; incompatible types in assignment とエラーがでます。 型はあってると思うんですが、、、 よろしくおねがいします。

  • 双方向リストのバブルソートについて

    双方向リストをバブルソートを用いてソートしたいです。 下記がプログラム(一部)ですが、ソートした後にリスト表示すると 無限ループに陥ります。 どこがいけないのでしょうか。 #include <stdio.h> #include <stdlib.h> struct cell{ int data; struct cell *next, *prev; }; void insert_head(struct cell **head, int num){ struct cell *p, *p1; p = *head; p1 = make_cell(); *head = p1; p1->data = num; p1->next = p; if(p1->next != (struct cell *)NULL){ p1->next = p; p->prev = p1; } } void print_list(struct cell *head){ struct cell *p; p = head; printf("data = \n"); while(p != (struct cell *)NULL){ printf("%d\n", p->data); p = p->next; } } void sort_list(struct cell **head){ struct cell *p, *p2; int i, n; n = 0; p = *head; while(p->next != (struct cell *)NULL){ p = p->next; n++; } for(i = 0, p = *head; i < n-2; i++){ if(p->data > p->next->data){ if(p == *head){ *head = p->next; }else{ p->prev->next = p->next; } p2 = p->next; p->next = p->next->next; p->next->next = p; p->next->next->prev = p; p->next->prev = p->prev; p->prev = p2; }else p = p->next; } } int main(void){ struct cell *head = (struct cell *)NULL; int n; while(1){ printf("1:Insert head 2:Insert tail 3:Delete 4:List 5:Sort 6:Exit\n"); scanf("%d", &n); switch(n){ case 1: printf("num = "); scanf("%d", &n); insert_head(&head, n); break; case 2: printf("num = "); scanf("%d", &n); insert_tail(&head, n); break; case 3: printf("num = "); scanf("%d", &n); delete_cell(&head, n); break; case 4: print_list(head); break; case 5: sort_list(&head); break; case 6: return 0; break; } } }

  • 構造体とポインタ配列

    現在C言語の勉強をしております。 環境はwindowsXP、コンパイラはVC6.0です。 構造体と、ポインタの配列についてなのですが、 以下のような構造体が宣言されている時に、リスト構造にデータがいくつか入っているとします。 // 構造体 typedef struct address { unsigned char names[NAME_SIZE+1]; /* 名前 */ char tels[TEL_SIZE + 1]; /* 電話番号 */ struct address *prev; /* 前へのポインタ */ struct address *next; /* 次へのポインタ */ }Address, *a_pt; そのリスト構造を先頭要素か順番にポインタ配列に格納するには以下の方法ではおかしいでしょうか? /* ポインタ配列を用意する */ Address *array[MAX_COUNT]; /* top_ptは先頭のポインタです */ pt = top_pt; /* データがなくなるまで配列へ格納する */ while(pt != NULL){ array[count++] = pt; pt = pt->next; } /* 配列の最後はNULLとする */ array[count] = NULL; また、配列の中身を確認する方法としては、 printf("配列の中身:%s\n", array[0]->names); では、アドレスが表示されてしまうのかな・・と思ったら、accessViolationで落ちてしまいました・・・。 中身はどうしたらデバッグ出来ますでしょうか? そもそも、以下の2つは何か違いはありますか? Address *ptA[100]; a_pt ptB[100]; 皆さん、どうかよろしくお願いいたします。 理解不能な場合はご指摘ください。

  • ファイルから構造体へデータを格納(動的メモリ割り当て)

    C言語の勉強をしいております。 typedef struct address { char names[32]; /* 名前 */ char tels[32]; /* 電話番号 */ struct address *prev; /* 前のリスト */ struct address *next; /* 次のリスト */ }Address; という構造体へ、ファイルから読み込んだテキストデータ(名前と電話番号がTABで区切られている)を格納したいのですが、配列ではなく、動的にメモリを確保しながら格納する方法を教えていただけないでしょうか? 処理の流れとしては、 ・1つめの構造体の*prevにはnullを入れておく。 ・1つめの構造体へファイルの1件目のデータを格納する。 ・ファイルのデータがまだある場合には、malloc関数を使ってメモリを確保し、malloc関数からの戻り値を1つめの構造体の*nextへ格納する。 ・構造体へ2件目のデータを格納する。 このような感じだろうという程度しか分からず、ソースも書けずにいます・・・。 配列を使用したサンプルはあるんですが、動的に処理を行う方法を教えていただけないでしょうか? よろしくお願いいたします。

  • 双方向リストで…、

    typedef struct score{ char name[40]; int eng; int math; int sci; struct score *next; struct score *prev; } SCORE; SCORE head; /* 双方向リストに要素を追加する */ void add_list(void) { SCORE *p, *new; in_file = fopen("input.txt", "r"); if ( in_file == NULL ){ printf("error: not open file.\n"); exit(0); } while( fgets(line, sizeof(line), in_file) != NULL ){ p = head.next; /* 先頭要素の次の要素のアドレス */ /* 新しく追加する要素のためのメモリ領域を確保する */ new = malloc( sizeof(SCORE) ); /* 新しい要素のデータを設定 */ sscanf(line, "%s %d %d %d", new->name, &new->eng, &new->math, &new->sci); new->next = p->next; /* 新しい要素の次の要素へのアドレスを設定 */ new->prev = p; /* 新しい要素の前の要素へのアドレスを設定 */ p->next->prev = new; /* 新しい要素の直後の要素のprevに、新しい要素のアドレスを設定 */ p->next = new; /* 新しい要素の直前の要素のnextに、新しい要素のアドレスを設定 */ } } ↑のところがうまくいきません。 何がだめか教えてください。

  • 線形リストのソートについて

    データ構造を線形リストとして、情報を管理するプログラムのソートについてです。 以下のプログラムはデータを入れ替えて、その後アドレスを入れ替えるようにしてソートを行っていますが、そうではなく線形リストなのでつなぎ替えるようにしてソートを行うプログラムを作成したいのですがわからないのでご教授をお願い致します。ソートは逐次決定で行ってます。 構造体の宣言として、nameとageとnextは氏名と年齢と次のポインタを指します。NAME_SORT、AGE_SORTはマクロです。 struct sortlist(struct PERSON *head) { int menu; struct PERSON person; /* 情報 */ struct PERSON move_person; /* 比較していく情報 */ struct PERSON work; /* 情報の一時的保存 */ struct PERSON temp; /* 作業用 */ struct PERSON temp_address; /* アドレス作業用 */ printf("ソート機能を選択:"); printf("%d:氏名\n",NAME_SORT); printf("%d:年齢\n",AGE_SORT); /* 交換処理 */ for(person = head; person -> next != NULL; person -> person -> next) { work = person; /* 交換データの探索 */ for(move_person = person -> next; move_person != NULL; move_person -> next) { switch(menu) { case NAME_SORT: if(strcmp(work -> name, move_person -> name) > 0) { work = move_person; } break; case NAME_SORT: if(work -> age > move_person -> age) { work = move_person; } break; default: printf("機能以外が選択されました"); return head; } if(work != person) { /* 情報の交換 */ temp = *person; *person = *work; *work = temp; /* アドレスの交換 */; temp_address = employee -> next; person -> next = work -> next; work -> next = temp_address; } } } } printf(“ソート完了”); }

  • 連結リストによるデータ管理プログラムの解説

    ★から★までのプログラムが、各行ごとにどのような動きをしているのか簡潔な言葉で説明を書いていただきたいのです。必要がないと判断した行はとばして下さって構いません。 (例) printf("hello!"); …hello!と表示 if(a==0){ …aが0なら #include <stdio.h> #include <stdlib.h> struct CELL{ struct CELL *next; char data; }; /* Head CELL CELL CELL +-------+ +-------+ +-------+ +-------+ | ? | *----> | 5 | *----> | 6 | *----> | 8 | / | +-------+ +-------+ +-------+ +-------+ */ main(void){★ struct CELL head; struct CELL *p, *wp; char a; head.next=NULL; printf("?\n"); scanf("%c %*c",&a); while(a!='0'){ printf("mode?\n"); scanf("%c",&mode); if(mode=="a"){ p=&head; while(p->next!=NULL){ p=p->next; } wp=(struct CELL *)malloc(sizeof(struct CELL)); if(wp==NULL){ printf("cannot allocate enough memory.\n"); return 0; } p->next=wp; p->next->data=a; p->next->next=NULL; printf("?\n"); scanf("%c %*c",&a); } if(mode=="p"){ printf("\n\nNow...\n"); p=&head; while(p->next!=NULL){ printf("%c --> \n",p->next->data); p=p->next; } printf("NULL\n"); if(mode=="d"){ p=&head; while(p->next->data==a){ p=p->next; } if(p==NULL) break; wp=p->next->next; while(p->next->data==a) p=wp;★ } } return 0; }

  • 線形リスト

    こんにちわ。今、大学で線形リストの勉強してるのですがよくわかりません。 ↓のプログラムで (1)10個のIDを受け取って受け取った順にリストを作るプログラム(各要素の値のアドレスとそのnextの値を表示してリストになっていることを確認する。) (2) (1)のプログラムを拡張して、リストを作ったあと、1から10までの間の整数nを入力として受け取り、リストのn番目の要素のIDを表示プログラムを書け。 の2つのことをしたいんですけど、どのようにすればいいのですか?どなたか回答おねがいします。 #include<stdio.h> #include<stdlib.h> struct list{ int ID; struct list *next; }; int main(int argc, char* argv[]) { struct list *top; top=(struct list *)malloc(sizeof(struct list)); //struct list 型の大きさの領域を1つ確保 //topがそこを指している状態にする //printf("IDを10個入力してください"); if(top == NULL){ //メモリが足りないと値がNULLになってします printf("メモリは確保できません\n"); exit(1); //強制終了。プログラムはココで終わってしまいます } top->next=NULL; top->ID=1; //ポインタtopが指している構造体のIDの値を変えている top->next=(struct list*)malloc(sizeof(struct list)); //もう1つ作ります //top->next==NULL (メモリ確保に失敗)の処理は省略 (top->next)->next=NULL; (top->next)->ID=5; //これで下図のような状態になります; return 0; }

  • 線形リスト(C言語)

    線形リストでn番目のIDを表示するプログラムを作っていますが、なぜか実行すると強制終了してしまいます。 コンパイルエラーは起きていないので、原因がさっぱりわかりません。 どなたかご教授お願いします。 #include <stdio.h> #include <stdlib.h> struct list{ int ID; struct list *next; }; int main(void) { struct list *top, *a; int i, n, x; a = NULL; for(i = 1; i < 11; i++) { printf("%d番目のIDを入力: " ,i); scanf("%d" ,&x); top = (struct list *)malloc(sizeof(struct list)); top->ID = x; top->next = a; a = top; } printf("何番目のIDを表示しますか: "); scanf("%d" ,&n); for(i = 1; i < 11; i--) { if(i == n) printf("%d" ,top->ID); top = top->next; } free((top->next->next->next->next->next->next->next->next)->next); free((top->next->next->next->next->next->next->next)->next); free((top->next->next->next->next->next->next)->next); free((top->next->next->next->next->next)->next); free((top->next->next->next->next)->next); free((top->next->next->next)->next); free((top->next->next)->next); free((top->next)->next); free(top->next); free(top); return 0; }

  • 構造体のリスト削除

    かれこれ1時間くらい悩んでいて 問題として 関数delete()を作成し、プログラムを完成させよ(~yabuki/p7.c)。 関数delete()は、与えられたデータをリストから削除するものである。 ただし、データが先頭であっても動作しなければならない。 次のように出力されるはずである。 NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> END PREV jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> END PREV hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END NEXT sunyon[23] -> END PREV sunyon[23] -> END list ha nakunarimasita /*******/の間に5行のプログラムを入れる。それ以外にmain()関数を 変更してはならない。 .........;の部分に構造体のメンバーを定義せよ。 というもので、Deleteしていくプログラムをつくりたいのですが NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> END PREV jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END セグメントエラー となり、続きができていません。 delete関数のif(p->next != NULL){ のところだけやると 最後まで出るみたいですが、うまくいってません よろしくおねがいします。 ↓ソースです・・・ #include <stdio.h> #include <string.h> struct kara { char name[16]; int age; struct kara *next; struct kara *prev; }; struct kara * delete(struct kara *,struct kara *); struct kara * findend(struct kara *); void* printforw(struct kara *); void* printback(struct kara *); int main() { struct kara a, x, f, m, c, *start, *end, *p; char name[128]; strcpy(a.name, "gyuri"); a.age = 23; strcpy(x.name, "sunyon"); x.age = 23; strcpy(f.name, "nicole"); f.age = 20; strcpy(m.name, "hara"); m.age = 20; strcpy(c.name, "jiyon"); c.age = 17; a.next = &x; x.next = &f; f.next = &m; m.next = &c; c.next = NULL; /********************* 5 lines */ a.prev = NULL; x.prev = &a; f.prev = &x; m.prev = &f; c.prev = &m; /*********************/ start = &a; end = findend(start); printforw(start); printback(end); printf("\n"); p = &c; start = delete(start, p); if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } printf("\n"); x.next = NULL; p = &a; start = delete(start, p); if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } printf("\n"); p = start; start = delete(start, p); //de senntou wo kaesu if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } return 0; } struct kara * delete (struct kara *start,struct kara *p) { /*if(p->next->next->next->next) { start = p->next->next->next->next; } */ for(p = start;p != NULL;p = p->next) { start = p->next->next->next; p = start; } /* if(p->next) { start = p->next; } if(p->prev) { start = p->prev; } if(p->next != NULL){ p->next->prev = p->prev; } } */ return p; } struct kara * findend(struct kara *start) { struct kara *pl; for(pl = start;pl != NULL; pl = pl->next){ start = pl; } return start; } void* printforw(struct kara *aa) { struct kara *pl; printf("NEXT "); for ( pl = aa; pl != NULL; pl = pl->next) { printf("%s[%d] -> ", pl->name, pl->age); } printf("END\n"); } void* printback(struct kara *cc) { struct kara *pl; printf("PREV "); //for( ; cc != NULL;cc = cc->prev){ for (pl = cc; pl != NULL; pl = pl->prev) { printf("%s[%d] ->", pl->name,pl->age); } printf("END\n"); }

専門家に質問してみよう