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

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

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

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

Q&A

解決済

2回答

1397閲覧

C言語 リスト構造について

Minochan

総合スコア14

C

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

0グッド

0クリップ

投稿2018/06/28 06:36

C言語にてリスト構造をつくり、1行の入力文字列をリスト化するというプログラムを作りました。
さらに入力されたリストの先頭の要素と、先頭と同じ要素をもつものを削除する関数remove_1st()とremove()を作りましたが、うまく機能しません。

わかる方、教えてください。

また、実現したい実行例は以下のとおりです。

bash

1./a.out 11414211356 2442356 3$ ./a.out aiueokakikukeko 4iueokkikukeko

実際に実行すると以下のようになります
削除する文字列が連続していない場合はうまく表示されるのですが、削除する文字列が連続している場合、うまく表示しません。

bash

1$ ./a.out 11414211356 214421356 3$ ./a.out aiueokakikukeko 4iueokkikukeko

C

1#include <stdio.h> 2#include <stdlib.h> 3 4struct node{ 5 char element; 6 struct node *next; 7}; 8 9 10struct node *initlist() { 11 struct node *n; 12 n=(struct node *)malloc(sizeof(struct node)); 13 n->next=NULL; 14 return n; 15} 16void insert(struct node *p, char x) { 17 struct node *n; 18 n=(struct node *)malloc(sizeof(struct node)); 19 while(p->next){ 20 p=p->next; 21 } 22 n->element=x; 23 n->next = NULL; 24 p->next=n; 25} 26 27 28void printlist(struct node *p) { 29 p = p->next; 30 while (p) { 31 putchar(p->element); 32 p = p->next; 33 } 34 putchar('\n'); 35} 36 37 38void delete(struct node *p){ 39 if(p->next!=NULL){ 40 p->next=p->next->next; 41 } 42} 43 44void remove_1st(struct node *p) { 45 char start=p->next->element; 46 struct node *tmp; 47 while(p->next!=NULL){ 48 //tmp=p; 49 50 if(p->next->element==start){ 51 52 delete(p); 53 } 54 p=p->next; 55 } 56} 57 58int main(int argc, char *argv[]) { 59 struct node *list, *head; 60 char *p; 61 62 if (argc<2) 63 exit(-1); 64 65 list = initlist(); 66 p = argv[1]; 67 for (; *p; p++) 68 insert(list, *p); 69 70 remove_1st(list); 71 printlist(list); 72 73 for (; list; ) { 74 head = list; 75 list = list->next; 76 free(head); 77 } 78 return 0; 79} 80

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

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

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

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

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

guest

回答2

0

ベストアンサー

C

1 if(p->next->element==start){ 2 3 delete(p); 4 }else{ 5 p=p->next; 6 }

deleteしたらリストを進めてはいけない
1番目をdeleteしたら、2番目が1番目にハマる。


C言語を学びたいなら、デバッグ環境を整えましょう。
Eclipseや、WindowsならVisualStudioなど。
これらはコードをワンステップづつ実行して、その都度、変数の内容をモニタしたりできます

投稿2018/06/28 06:48

編集2018/06/28 06:56
y_waiwai

総合スコア87719

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

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

0

3点指摘があります。

remove_1st で1文字目が取得できていない

c

1char start=p->next->element;

これ、2文字目です。

delete が現在位置の次の文字を消しているので混乱しやすい

コレ自体は間違いとは言えないですが、ポインタ位置の node を削除しないので読み手が大変混乱しやすいです。
ところで、 delete で参照がなくなるなら free したほうがいいですね。

削除した場合はポインタ移動しなくて良い

c

1if(p->next->element==start){ 2 delete(p); 3} 4p=p->next;

削除してポインタ位置も動かすとこうなります。

2 -> 1 -> 1 -> 3 ^ 2 -> 1 -> 3 ^ 2 -> 1 -> 3 ^

削除した場合はポインタ位置は動かさなくていいはずです。
具体的なケースを自分で紙に書いて動きを確認してみるのも一つのデバッグ作業なので、動きが読めなくなってきたらいじくり回す前に冷静になってよく確認してみましょう。

投稿2018/06/28 06:57

mather

総合スコア6753

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

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

tatamyiwathy

2018/06/28 08:51

char start=p->next->element; これは1文字目じゃないでしょうか?insert()では先頭のnodeに文字を代入していません。
mather

2018/06/28 08:58

なるほど、作成したノードに値をセットしているんですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問