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

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

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

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

Q&A

解決済

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

aoba-purines
aoba-purines

総合スコア12

C

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

3回答

0グッド

0クリップ

565閲覧

投稿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

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

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

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

回答3

1

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

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

総合スコア10837

spoofy_dragon👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

ベストアンサー

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

退会済みユーザー👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2022/11/09 03:46

こちらの回答が他のユーザーから「スパムと見受けられる内容を含む回答」という指摘を受けました。

2022/11/09 01:26

こちらの回答が複数のユーザーから「質問に対する回答となっていない投稿」という指摘を受けました。

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

総合スコア179

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

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);用いて~と書いてありましたね。失礼しました。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C

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