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

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

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

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

Q&A

解決済

1回答

4784閲覧

listでinsert文を挿入したいのですが、上手くデータが挿入されません

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2018/02/18 10:35

編集2018/02/18 10:56

http://ppp-lab.sakura.ne.jp/ProgrammingPlacePlus/algorithm/data_struct/003.html#library

にあるlistのプログラムで要素を挿入するinsert_elem()文があるのですが、
listのプログラムに組み込んで動作させたいのですが、上手くデータが挿入されません。
どこが悪いのでしょうか。教えてください。下が私が書き変えたコードです。

コード > //単方向線形リスト  #include <stdio.h> #include <string.h> #include <stdlib.h> // コマンド enum Cmd_tag { CMD_ADD, CMD_INSERT, CMD_DELETE, CMD_SEARCH, CMD_CLEAR, CMD_PRINT, CMD_EXIT, CMD_NUM }; // コマンド文字列の種類 enum CmdStr_tag { CMD_STR_SHORT, CMD_STR_LONG, CMD_STR_NUM }; // コマンドの戻り値 enum CmdRetValue_tag { CMD_RET_VALUE_CONTINUE, CMD_RET_VALUE_EXIT, }; // コマンド文字列 static const char* const CMD_STR[CMD_NUM][CMD_STR_NUM] = { { "a", "add" }, { "i", "insert" }, { "d", "delete" }, { "s", "search" }, { "c", "clear" }, { "p", "print" }, { "e", "exit" } }; static void init_head(void); static void print_explain(void); static void print_blank_lines(void); static enum CmdRetValue_tag get_cmd(void); static enum CmdRetValue_tag cmd_add(void); static enum CmdRetValue_tag cmd_insert(void); static enum CmdRetValue_tag cmd_delete(void); static enum CmdRetValue_tag cmd_search(void); static enum CmdRetValue_tag cmd_clear(void); static enum CmdRetValue_tag cmd_print(void); static enum CmdRetValue_tag cmd_exit(void); static void add_elem_front (int value); static int insert_elem(int value,int pos); static int delete_elem(int value); static void clear_list(void); static void print_list(void); static struct LinkedList_tag* search_elem(int value); static void get_line(char* buf, size_t size); // コマンド実行関数 typedef enum CmdRetValue_tag (*cmd_func)(void); static const cmd_func CMD_FUNC[CMD_NUM] = { cmd_add, cmd_insert, cmd_delete, cmd_search, cmd_clear, cmd_print, cmd_exit }; // 連結リスト型 struct LinkedList_tag { int value; struct LinkedList_tag* next; }; static struct LinkedList_tag gHead; int main(void) { init_head(); //グローバル変数gHead のメンバを初期化しています。 while( 1 ){ print_explain(); if( get_cmd() == CMD_RET_VALUE_EXIT ){ break; } print_blank_lines(); } return 0; } // 先頭要素を初期化 void init_head(void) { gHead.value = 0; gHead.next = NULL; } // 説明文を出力 void print_explain(void) { puts( "コマンドを入力して下さい。" ); printf( " 連結リストに要素を追加する: %s (%s)\n", CMD_STR[CMD_ADD][CMD_STR_SHORT], CMD_STR[CMD_ADD][CMD_STR_LONG] ); printf( " 連結リストに要素を挿入する: %s (%s)\n", CMD_STR[CMD_INSERT][CMD_STR_SHORT], CMD_STR[CMD_INSERT][CMD_STR_LONG] ); printf( " 連結リストから要素を削除する: %s (%s)\n", CMD_STR[CMD_DELETE][CMD_STR_SHORT], CMD_STR[CMD_DELETE][CMD_STR_LONG] ); printf( " 連結リストから要素を探す: %s (%s)\n", CMD_STR[CMD_SEARCH][CMD_STR_SHORT], CMD_STR[CMD_SEARCH][CMD_STR_LONG] ); printf( " 連結リストを空にする: %s (%s)\n", CMD_STR[CMD_CLEAR][CMD_STR_SHORT], CMD_STR[CMD_CLEAR][CMD_STR_LONG] ); printf( " 連結リストの中身を出力する: %s (%s)\n", CMD_STR[CMD_PRINT][CMD_STR_SHORT], CMD_STR[CMD_PRINT][CMD_STR_LONG] ); printf( " 終了する: %s(%s)\n", CMD_STR[CMD_EXIT][CMD_STR_SHORT], CMD_STR[CMD_EXIT][CMD_STR_LONG] ); puts( "" ); } //空白行を出力 void print_blank_lines(void) { puts( "" ); puts( "" ); } //コマンドを受け付ける enum CmdRetValue_tag get_cmd(void) { char buf[20]; enum Cmd_tag cmd; int i; get_line( buf, sizeof(buf) ); //print_explain()の中から //コマンドを選ぶ cmd = CMD_NUM; // for( i = 0; i < CMD_NUM; ++i ){ if( strcmp( buf, CMD_STR[i][CMD_STR_SHORT] ) == 0 || strcmp( buf, CMD_STR[i][CMD_STR_LONG] ) == 0 ){ cmd = i; //ここでコマンドを受け取る break; } } if( 0 <= cmd && cmd < CMD_NUM ){ return CMD_FUNC[i](); //コマンドを返している } else{ puts( "そのコマンドは存在しません。" ); } return CMD_RET_VALUE_CONTINUE; //そのコマンドは存在しないときはget_cmdを続ける } //addコマンドの実行 enum CmdRetValue_tag cmd_add(void) { char buf[40]; int value; puts( "追加する数値データを入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf, "%d", &value ); //文字列bufから書式format( "%d")にしたがって、 //scanf関数と同様の変換を行った入力を、 //指定されたアドレス(&value )に格納します。 add_elem_front( value ); //要素を追加する return CMD_RET_VALUE_CONTINUE; } //insertコマンドの実行 enum CmdRetValue_tag cmd_insert(void) { char buf[40],buf2[40]; int value,pos; puts( "挿入する数値データを入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf, "%d", &value ); //文字列bufから書式format( "%d")にしたがって、 //scanf関数と同様の変換を行った入力を、 //指定されたアドレス(&value )に格納します。 puts( "挿入する数値データをどこの数値の後に入力するか入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf2, "%d", &pos ); insert_elem( value,pos); //要素を挿入する return CMD_RET_VALUE_CONTINUE; } //deleteコマンドの実行 enum CmdRetValue_tag cmd_delete(void) { char buf[40]; int value; puts( "削除する数値データを入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf, "%d", &value ); if( delete_elem(value) >= 1 ){ puts( "要素を削除しました。" ); } else{ puts( "削除する要素は見つかりませんでした。" ); } return CMD_RET_VALUE_CONTINUE; } //searchコマンドの実行 enum CmdRetValue_tag cmd_search(void) { char buf[40]; int value; puts( "探索する数値データを入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf, "%d", &value ); if( search_elem(value) == NULL ){ printf( "%d は連結リスト中に存在しません。\n", value ); } else{ printf( "%d は連結リスト中に存在します。\n", value ); } return CMD_RET_VALUE_CONTINUE; } //clearコマンドの実行 enum CmdRetValue_tag cmd_clear(void) { clear_list(); return CMD_RET_VALUE_CONTINUE; } //printコマンドの実行 enum CmdRetValue_tag cmd_print(void) { print_list(); return CMD_RET_VALUE_CONTINUE; } //exitコマンドの実行 enum CmdRetValue_tag cmd_exit(void) { puts( "終了します。" ); return CMD_RET_VALUE_EXIT; } // 要素を追加する // 引数: // value: 追加する要素の数値データ。 void add_elem_front(int value) { struct LinkedList_tag* elem;//新しいデータの先頭アドレス // 追加する要素を作る elem = malloc( sizeof(struct LinkedList_tag) ); if( elem == NULL ){ fputs( "メモリ割り当てに失敗しました。", stderr ); exit( 1 ); } elem->value = value; elem->next = gHead.next; // 先頭に追加するといっても、ダミーの先頭要素よりも手前に置くのではなくて、 // ダミーの直後に挿入します。 // ダミーが持つ nextポインタの値を、追加する要素の nextポインタに代入し、 // ダミーの nextポインタは、追加した要素を指すように書き換えます。 gHead.next = elem; // ダミーの先頭要素の次は、追加した要素になる } // 要素を挿入する // 引数: // value: 挿入する要素の数値データ。 // pos : 挿入場所の前の数値データ。この値の直後に挿入する int insert_elem(int value,int pos) { struct LinkedList_tag* p; struct LinkedList_tag* elem; // 挿入位置を探す p = search_elem(pos); if( p == NULL ){ return 0; } // 挿入する要素を作る elem = malloc( sizeof(struct LinkedList_tag) ); if( elem == NULL ){ fputs( "メモリ割り当てに失敗しました。", stderr ); exit( 1 ); } elem->value = value; elem->next = p->next; // p と p->next の隙間に挿入する p->next = elem; return 1; } int delete_elem(int value) { struct LinkedList_tag* p = gHead.next; struct LinkedList_tag* prev = &gHead; int count = 0; while( p != NULL ){ if( p->value == value ){ prev->next = p->next; free( p ); p = prev->next; ++count; } else{ prev = p; p = p->next; } } return count; } //要素を空にする void clear_list(void) { struct LinkedList_tag* p = gHead.next; struct LinkedList_tag* prev = &gHead; while( p != NULL ){ prev->next = p->next; free( p ); p = prev->next; } } //要素を出力する void print_list(void) { struct LinkedList_tag* p = gHead.next; if( p == NULL ){ puts( "リストは空です。" ); return; } while( p != NULL ){ printf( "%d\n", p->value ); p = p->next; } } struct LinkedList_tag* search_elem(int value) { struct LinkedList_tag* p = gHead.next;   while( p != NULL ){ if( p->value == value ){ return p; } p = p->next; } return NULL; } void get_line(char* buf, size_t size) { fgets(buf, size, stdin); char* p = strchr(buf, '\n'); if (p != NULL) { *p = '\0'; } } 実行結果 naka@naka ~/kadai/kadai9-8 $ gcc -o LST15 LST15.c -Wall naka@naka ~/kadai/kadai9-8 $ LST15 a 追加する数値データを入力して下さい。 4 コマンドを入力して下さい。  連結リストに要素を追加する: a (add)  連結リストに要素を挿入する: i (insert)  連結リストから要素を削除する: d (delete)  連結リストから要素を探す: s (search)  連結リストを空にする: c (clear)  連結リストの中身を出力する: p (print)  終了する: e(exit) a 追加する数値データを入力して下さい。 5 コマンドを入力して下さい。  連結リストに要素を追加する: a (add)  連結リストに要素を挿入する: i (insert)  連結リストから要素を削除する: d (delete)  連結リストから要素を探す: s (search)  連結リストを空にする: c (clear)  連結リストの中身を出力する: p (print)  終了する: e(exit) a 追加する数値データを入力して下さい。 9 コマンドを入力して下さい。  連結リストに要素を追加する: a (add)  連結リストに要素を挿入する: i (insert)  連結リストから要素を削除する: d (delete)  連結リストから要素を探す: s (search)  連結リストを空にする: c (clear)  連結リストの中身を出力する: p (print)  終了する: e(exit) p 9 5 4 コマンドを入力して下さい。  連結リストに要素を追加する: a (add)  連結リストに要素を挿入する: i (insert)  連結リストから要素を削除する: d (delete)  連結リストから要素を探す: s (search)  連結リストを空にする: c (clear)  連結リストの中身を出力する: p (print)  終了する: e(exit) i 挿入する数値データを入力して下さい。 6 挿入する数値データをどこの数値の前に入力するか入力して下さい。 5 コマンドを入力して下さい。  連結リストに要素を追加する: a (add)  連結リストに要素を挿入する: i (insert)  連結リストから要素を削除する: d (delete)  連結リストから要素を探す: s (search)  連結リストを空にする: c (clear)  連結リストの中身を出力する: p (print)  終了する: e(exit) p 9 5 4 変化なし(6が挿入されない) */

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

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

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

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

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

guest

回答1

0

ベストアンサー

//insertコマンドの実行
enum CmdRetValue_tag cmd_insert(void)
{
char buf[40],buf2[40];
int value,pos;

puts( "挿入する数値データを入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf, "%d", &value ); //文字列bufから書式format( "%d")にしたがって、 //scanf関数と同様の変換を行った入力を、 //指定されたアドレス(&value )に格納します。 puts( "挿入する数値データをどこの数値の後に入力するか入力して下さい。" ); fgets( buf, sizeof(buf), stdin ); sscanf( buf2, "%d", &pos ); insert_elem( value,pos); //要素を挿入する return CMD_RET_VALUE_CONTINUE;

}
の下から6行目fgets( buf, sizeof(buf), stdin );をfgets( buf2, sizeof(buf), stdin );に変更しました。単純なミスでした。それでも1日かかりました。

投稿2018/02/18 12:52

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問