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

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

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

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

Q&A

解決済

3回答

1294閲覧

連結リストを用いて、入力した位置にアルファベットを挿入するプログラムを作ろうとしたが、Segmentation Faultが発生した。

aoba-purines

総合スコア13

C

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

0グッド

0クリップ

投稿2022/11/08 16:40

編集2022/11/08 17:09

連結リストを用いて、入力した位置にアルファベットを挿入するプログラムを作ろうとしましたが、Segmentation Faultが発生してしまいました。デバッガgdbもうまく作動しません。どのようにすれば直るのか分かりません。問題は以下の通りです。

頭のある連結リストに対し、先頭に節点を挿入する関数

void insert(list l, elementtype e);

を用いて標準入力の 1 行目に与えられる文字列から char 型のリストを作成し、以降の入力の各行に与えられる「位置」と「アルファベット 1 文字」に対し、その位置にアルファベットを挿入するプログラムを作成せよ。「位置」は整数値で与えられ、0 番目が先頭を表すものとする。また、標準出力には、標準入力から 1 行入力されるごとに、その時点でのリストの内容を先頭から順に文字列として並べたものと改行文字を出力する。「位置」がその時点でのリストの長さより大きい場合には、末尾に挿入するものとせよ。

実行例

Big 2 n 4 o  /入力終わり/ Big Bing Bingo
ink 0 L 42 d 4 e /入力終わり/ ink Link Linkd Linked

該当のソースコード

#include<stdio.h> #include<stdlib.h> typedef struct node* list; typedef char elementtype; struct node { elementtype element; struct node* next; }; /* 要素e,次に繋がるノードxを示すノードを作る */ struct node *initlist (elementtype e, struct node *x) { struct node *n; n = (struct node *) malloc (sizeof (struct node) ); n->element= e; n -> next = x; return n; } /* リストに要素eのノードを挿入*/ void insert(list*l, elementtype e) { list new ; new = initlist(e,*l); *l = new; } /* 表示 */ void print_list(list l) { while ( l != NULL) { printf("%d", l->element); l = l->next; } } int main() { int i, s; char c, buf[128]; list l ; /* リストlの初期化 */ l = (struct node *) malloc (sizeof (struct node) ); l ->next =NULL; fgets(buf,sizeof(buf),stdin); /* ← 1 行目を buf に読み込み */    for(i=0; (c = buf[i])!='\n'; ++i) {/* ← 1 文字ずつ処理する for 文 */ insert(&l,c);/* ※ここで c をリスト l の末尾に挿入 */ l=l->next; } print_list(l); while(fgets(buf,sizeof(buf),stdin) != NULL) {/* ← 2 行目以降を順に buf に読み込み */ sscanf(buf,"%d %c", &i, &c); for(s = 0 ;s < i ;s++){ l=l->next; } insert(&l,c);/* ※ここでリスト l の i 番目に c を挿入 */ print_list(l); } return 0; }

補足情報(FW/ツールのバージョンなど)

unix gcc 4.8.5

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

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

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

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

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

jimbe

2022/11/08 20:42 編集

デバッガに頼る前に、コードを見直して頭の中でシミュレートしてみては如何でしょうか。 > insert(&l,c);/* ※ここで c をリスト l の末尾に挿入 */ insert は > 頭のある連結リストに対し、先頭に節点を挿入する関数 ではありませんか? ですので変数 l は insert を呼んでいる for の中で > l=l->next; として書き換えてしまっていますが、それ以降の処理はできますか? ついでに、 insert が先頭に追加してそのアドレスを設定してくれるのならば、1行目の処理の際は文字列の最後から先頭に向かって処理をして行けば、アドレスの処理などしなくても、最後にはリストの先頭が設定されていることになるはずです。 なお、 fgets は読み込んだ"サイズ-1"バイトの中に改行が無かった場合は改行コード無しで戻りますので、改行コードまで処理をするという条件では終わらない可能性があります。
jimbe

2022/11/09 02:38

過去問見ると課題やってるだけなんですね…。
guest

回答3

0

表示の関数の不具合とか「頭のある連結リスト」の頭が無さそうとかは大丈夫だったんでしょうか。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5typedef struct node* list; 6typedef char elementtype; 7struct node { 8 elementtype element; 9 struct node* next; 10}; 11 12struct node *initlist(elementtype e, struct node *x) { 13 struct node *n = (struct node *)malloc(sizeof(struct node)); 14 n->element = e; 15 n->next = x; 16 return n; 17} 18 19void insert(list *l, elementtype e) { 20 *l = initlist(e, *l); 21} 22 23void printlist(list l) { 24 for( ; l != NULL; l=l->next) printf("%c", l->element); 25 printf("\n"); 26} 27 28int main() { 29 char buf[128]; 30 fgets(buf, sizeof(buf), stdin); 31 int len = strlen(buf); 32 if(len>0 && buf[len-1]=='\n') buf[len-1] = '\0'; 33 34 struct node head; 35 head.next = NULL; //文字列の先頭ノードのアドレス 36 for(int i=strlen(buf)-1; i>=0; i--) insert(&head.next, buf[i]); 37 38 printlist(head.next); 39 40 while(fgets(buf,sizeof(buf),stdin) != NULL) { 41 int index; 42 char chara; 43 sscanf(buf,"%d %c", &index, &chara); 44 45 list np = &head; 46 for(int i=0; i<index && np->next!=NULL; i++, np=np->next); 47 insert(&np->next, chara); 48 49 printlist(head.next); 50 } 51 52 return 0; 53}

投稿2022/11/09 04:31

jimbe

総合スコア12951

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

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

0

ベストアンサー

Segmentation fault (core dumped)
Main.cpp:46:32: warning: treating Unicode character as whitespace [-Wunicode-whitespace] fgets(buf,sizeof(buf),stdin); /* ← 1 行目を buf に読み込み */   ^~ Main.cpp:46:78: warning: treating Unicode character as whitespace [-Wunicode-whitespace] fgets(buf,sizeof(buf),stdin); /* ← 1 行目を buf に読み込み */   ^~ Main.cpp:47:1: warning: treating Unicode character as whitespace [-Wunicode-whitespace]  for(i=0; (c = buf[i])!='\n'; ++i) {/* ← 1 文字ずつ処理する for 文 */ ^~ 3 warnings generated.

投稿2022/11/08 17:00

atcoderyellow

総合スコア481

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

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

0

質問者様のコードに全角スペースが含まれているのでそちらは削除してください。

Segmentation Faultが発生してしまいました。

C

1for(i=0; (c = buf[i])!='\n'; ++i) {/* ← 1 文字ずつ処理する for 文 */ 2 insert(&l,c);/* ※ここで c をリスト l の末尾に挿入 */ 3 l=l->next; 4 }

最後の l = l->next のせいで毎回リストの最後に戻ってきています。
その後のwhile文の中でまたl = l->nextをしていますが、リストの最後のl->nextはNULLです。
ここでは l のアドレスにNULLを代入することになりますのでアクセス例外が起きてしまいます。

ですので、一行目の処理は以下のようにしたほうが良いかと思います。

C

1fgets(buf,sizeof(buf),stdin);/* ← 1 行目を buf に読み込み */ 2 for(i=0; (c = buf[i])!='\n'; ++i) {/* ← 1 文字ずつ処理する for 文 */ 3 if (i == 0) { 4 l->element = buf[0]; /* 先頭リストのelementに不定の値を入れない処理 */ 5 } 6 else { 7 insert(&l, c);/* ※ここで c をリスト l の末尾に挿入 */ 8 } 9 } 10 last = l;

投稿2022/11/09 02:58

編集2022/11/09 04:09
ALOHAMS

総合スコア195

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

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

jimbe

2022/11/09 03:05

"next" ですので、『リストの頭』と言うよりは『リストの最後』の方がリンクのイメージに合う気がします。
jimbe

2022/11/09 03:17

課題でしょうから、リストの構造の変更は出来なさそうですが。
aoba-purines

2022/11/09 03:19

解決しました。 ありがとうございました。
ALOHAMS

2022/11/09 04:14

Jimbe様 >"next" ですので、『リストの頭』と言うよりは『リストの最後』の方がリンクのイメージに合う気がします。 確かにそちらの方がイメージに合いますね。回答本文を修正しました。 >課題でしょうから、リストの構造の変更は出来なさそうですが。 void insert(list l, elementtype e);用いて~と書いてありましたね。失礼しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.41%

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

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

質問する

関連した質問