質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

2549閲覧

c言語 リスト構造について...

maikeru

総合スコア68

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/10/15 08:23

編集2017/10/15 09:45

###前提・実現したいこと
最近C言語でリスト構造を勉強したので自己流でリスト構造のプログラムを作成したのですが正常に作動しません。どなたか解決法を教えてください。

説明不足だったので補足します。
データの追加を行おうとすると動作が停止するのですがadd_data()の修正を試みたのですが、修正箇所が分かりません。

###該当のソースコード

C

1#define _CRT_SECURE_NO_WARNINGS 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5 6/*データ*/ 7typedef struct { 8 int num; //学籍番号下三桁 9 char name[16]; //氏名 10}data_t; 11 12/*ノード*/ 13typedef struct node { 14 data_t data; //データ 15 struct node *nextnode; //後ろのノードへのポインタ 16}node_t; 17 18/*関数プロトタイプ宣言*/ 19node_t *make_node(data_t, node_t *); 20void add_data(node_t *); 21void remove_data(node_t *); 22void search_data(node_t *); 23void show_data(node_t *); 24void release(node_t *); 25 26int main(void) 27{ 28 int menu; 29 node_t *node=NULL; 30 31 do { 32 puts(""); 33 puts("***メニューの選択***"); 34 puts(" 1.データの追加"); 35 puts(" 2.データの削除"); 36 puts(" 3.データの検索"); 37 puts(" 4.データの表示"); 38 puts(" 5.終了"); 39 40 printf("メニューの選択:"); 41scanf("%d", &menu); 42 puts(""); 43 44 switch (menu) 45 { 46 case 1: add_data(node); break; 47 case 2: remove_data(node); break; 48 case 3: search_data(node); break; 49 case 4: show_data(node); break; 50 case 5: puts("プログラムを終了"); break; 51 default:puts("番号を再入力"); break; 52 } 53 } while (menu != 5); 54 55 release(node); 56 system("pause"); 57 return 0; 58} 59 60/*新規ノードの作成*/ 61node_t *make_node(data_t data, node_t *nextnode) 62{ 63 node_t *p; 64 65 p = malloc(sizeof(node_t)); 66 if (p == NULL) { 67 puts("領域確保に失敗"); 68 return NULL; 69 } 70 else { 71 p->data = data; 72 p->nextnode = nextnode; 73 return p; 74 } 75} 76 77/*データの追加*/ 78void add_data(node_t *node) 79{ 80 data_t data; 81 node_t *p=node; 82 83 puts("***追加するデータの入力***"); 84 printf("学籍番号の下二桁の番号:"); scanf("%d", &data.num); 85 printf("氏名:"); scanf("%s", data.name); 86 87 while (p->nextnode != NULL) { 88 p = p->nextnode; 89 } 90 p = make_node(data, NULL); 91} 92 93/*データの表示*/ 94void show_data(node_t *node) 95{ 96 node_t *p=node; 97 98 if (p ==NULL) { 99 puts("データがありません。データを追加してください。"); 100 return; 101 } 102 while (p!=NULL){ 103 printf("番号%*s氏名\n",6,""); 104 printf("%2d %10s\n", (p->data).num, (p->data).name); 105 p = p->nextnode; 106 } 107} 108 109/*データの削除*/ 110void remove_data(node_t *node) 111{ 112 int num; 113 node_t *pre; 114 if(node==NULL) 115 puts("データは見つかりませんでした。"); return; 116 puts("***データの削除***"); 117 printf("番号の入力:"); scanf("%d", &num); 118 119 while (node->nextnode != NULL) { 120 if ((node->data).num == num) { 121 pre = node->nextnode; 122 free(node); 123 return; 124 } 125 pre = node; 126 node = node->nextnode; 127 } 128 puts("データは見つかりませんでした。"); 129} 130 131/*データの検索*/ 132void search_data(node_t *node) 133{ 134 int num; 135 node_t *p=node; 136 137 puts("***データの検索***"); 138 printf("番号の入力:"); scanf("%d", &num); 139 140 if (node == NULL) 141 puts("データは見つかりませんでした"); return; 142 while (p->nextnode != NULL) { 143 if ((p->data).num == num) { 144 puts("---データを発見---"); 145 printf("氏名:%s\n", (p->data).name); 146 return; 147 } 148 p = p->nextnode; 149 } 150 puts("データは見つかりませんでした"); 151} 152 153/*データの後処理*/ 154void release(node_t *node) 155{ 156 node_t *p; 157 158 if (node = NULL) return; 159 while (node->nextnode != NULL) { 160 p = node; 161 node = node->nextnode; 162 free(p); 163 } 164}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2017/10/15 09:06

どのように上手くいかないのか書いてください。コンパイル出来ない、実行中落ちる、etc.『上手くいかない』という表現は広すぎます。また、特定の入力に対して上手く動作しない場合、その入力と出力、同時に理想とする出力を書いてください。
LouiS0616

2017/10/15 09:07

また、コードのインデントが崩れて非常に読みづらくなっています。Teratailには、コードを見やすく表示する機能があります。編集画面を開き、コードを選択した状態で<code>ボタンを押してください。
guest

回答4

0

”正常に作動しません。”では分かりません。
release()内、if (node = NULL) return;・・・これではreturnしません。
"_CRT_SECURE_NO_WARNINGS"をセットしているのでワーニングが出ないせいだと思います。scanf()のワーニングを消すためだと思いますがワーニングを見ないようにするのは止めた方がいいですよ。

remove_data()内、if (node == NULL)
puts("データは見つかりませんでした."); return; ←このreturnはif文の外にあるためこの後の処理は実行されません。

投稿2017/10/15 09:28

編集2017/10/15 09:40
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

メインの node_t *node=NULL;でリストの先頭要素を指すつもりですね。
最初の要素を入れる場合を考えてください。
nodeを引数で渡してもnodeの値は変わりませんから、add_node(node)の呼んだ先で何をしてもmainのnodeはNULLのままです。つまり、add_nodeの中をどう改造しても駄目ってこと。

まずはこれが分からないと、いろいろな人のアドバイスが何を言われているか理解できないかも。

対策はいくつかあって
・要素数がn個の時にリストにはn+1個node_t要素がある(「リスト末尾」を表すnode_tを1個置く)ようにする。
・add_nodeを「現在のリスト先頭(空ならNULL)を受け取って、更新したリストの先頭へのポインタを返す関数」に変えること。
・二重ポインタを使いadd_node(node_t**node)に &nodeを渡す。
・などなど

投稿2017/10/24 01:03

a_saitoh

総合スコア702

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

全ケースのテストは行っていませんが取り合えず動く程度ですので参考まで

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> /*データ*/ typedef struct { int num; //学籍番号下三桁 char name[16]; //氏名 }data_t; /*ノード*/ typedef struct node { data_t data; //データ struct node *nextnode; //後ろのノードへのポインタ }node_t; /*関数プロトタイプ宣言*/ node_t *make_node(data_t, node_t *); node_t *add_data(node_t *); node_t *remove_data(node_t *); void search_data(node_t *); void show_data(node_t *); void release(node_t *); int main(void) { int menu; node_t *node=NULL; do { puts(""); puts("***メニューの選択***"); puts(" 1.データの追加"); puts(" 2.データの削除"); puts(" 3.データの検索"); puts(" 4.データの表示"); puts(" 5.終了"); printf("メニューの選択:"); scanf("%d", &menu); puts(""); switch (menu) { case 1: node=add_data(node); break; case 2: node=remove_data(node); break; case 3: search_data(node); break; case 4: show_data(node); break; case 5: puts("プログラムを終了"); break; default:puts("番号を再入力"); break; } } while (menu != 5); release(node); // system("pause"); コメント return 0; } /*新規ノードの作成*/ node_t *make_node(data_t data, node_t *nextnode) { node_t *p; p = malloc(sizeof(node_t)); if (p == NULL) { puts("領域確保に失敗"); return NULL; } else { p->data = data; p->nextnode = nextnode; } return p; } /*データの追加*/ node_t *add_data(node_t *node) { data_t data; node_t *p=node; puts("***追加するデータの入力***"); printf("学籍番号の下二桁の番号:"); scanf("%d", &data.num); printf("氏名:"); scanf("%s", data.name); while ( node != NULL && p->nextnode != NULL) { p = p->nextnode; } if (node == NULL) { node=make_node(data, NULL); }else{ p->nextnode=make_node(data, NULL); } return node; } /*データの表示*/ void show_data(node_t *node) { node_t *p=node; if (p == NULL) { puts("データがありません。データを追加してください。"); return; } while (p!=NULL){ printf("番号%*s氏名\n",6,""); printf("%2d %10s\n", (p->data).num, (p->data).name); p = p->nextnode; } } /*データの削除*/ node_t *remove_data(node_t *node) { int num; node_t *head=node; node_t *pre=NULL; if(node==NULL){ puts("データは見つかりませんでした。"); return NULL; } puts("***データの削除***"); printf("番号の入力:"); scanf("%d", &num); while (node->nextnode != NULL) { if ((node->data).num == num) { if (pre == NULL){ return node->nextnode; }else{ pre->nextnode = node->nextnode; free(node); return head; } } pre = node; node = node->nextnode; } puts("データは見つかりませんでした。"); return head; } /*データの検索*/ void search_data(node_t *node) { int num; node_t *p=node; puts("***データの検索***"); printf("番号の入力:"); scanf("%d", &num); if (node == NULL) { puts("データは見つかりませんでした"); return; } while (p->nextnode != NULL) { if ((p->data).num == num) { puts("---データを発見---"); printf("氏名:%s\n", (p->data).name); return; } p = p->nextnode; } puts("データは見つかりませんでした"); } /*データの後処理*/ void release(node_t *node) { node_t *p; if (node == NULL) return; p = node; release(p->nextnode); free(p); }

投稿2017/10/16 02:25

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maikeru

2017/10/23 04:44

ありがとうございました。とても勉強になりました。
guest

0

データの追加を行おうとすると動作が停止するのですがadd_data()の修正を試みたのですが、修正箇所が分かりません。

初期値NULLのままであるnodeの実体を参照しようとしているからでしょう。


cateyeさんが既にご指摘されているとおり、プログラムに様々な穴があります。
完成させて初めて動かすのではなく、確実にエラーを潰してから拡張した方がよいです。
特に慣れないうちは、エラーメッセージを減らせる点で有用です。

投稿2017/10/15 09:55

LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問