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

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

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

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

Q&A

解決済

2回答

936閲覧

C言語 自己参照構造体のエラー改善について

ccodereader

総合スコア7

C

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

0グッド

0クリップ

投稿2022/05/14 05:03

プログラミング初心者です。
C言語の課題で調べながらやっているのですが、エラーが続き泣きそうです。
ヒントだけでも頂けると非常に助かります。

【 課題文 】 :

自己参照構造体を使って単語を登録するプログラムを作りましょう.forを使った繰返しの中でfgetsを使って単語を入力します.Control-Dキーが入力されたら繰返しから抜け出し,登録した単語を順番に表示します.あらかじめ繰返しの数が分かっていないので,動的にメモリを確保する必要があります.Control-D が入力されると,fgets はファイル(標準入力) が終りになったと判断し,NULLポインタを返すので,それによって入力の終了をプログラム中で検出できます.

1行入力のために用意するchar 型の配列の大きさは、マクロで定義し、1024としてください。1行入力はfgetsを用い、行末の改行文字(\n)は、strchr()を用いて検出し、取り除いてから処理するようしてください。また、自己参照構造体は、以下のようにしてください。

struct list { struct list *next; char *name; };

control-dの検出は、fgets()の返値をNULLと比較して行ってください。

char *p; ... for(;;){ p = fgets(.....); if(p == NULL){ break; } ... }

プログラムを動作させ、キーボードから何行か入力して最後にcontrol-d(CTRL-D, ^D)を入力すると、以下のように入力された文字列がそのまま入力した行の順番に表示されるようにしなければならないようです。

%./kadai ABC 123 XYZ ^D ABC 123 XYZ %

【 現状 】 :

#include <stdio.h> #include <string.h> #include <stdlib.h> //1行入力のために用意するchar型の配列の大きさはマクロで定義し1024 #define MAXLINE 1024 //自己参照構造体を定義 struct list { struct list *next; char *name; }; int main(){ char input[MAXLINE]; //構造体型のポインタ char *p, *start; //forを使った繰返しの中でfgetsを使って単語を入力 for(;;){ p = fgets(input,MAXLINE,stdin); //pがNULLの時、入力の終了 if(p == NULL){ break; } p = strchr(input,'\n'); if(p != NULL){ //1回目のループ -- 先頭の構造体を生成 p = malloc(sizeof(struct list)); start = p; }else{ //2回目以降 -- 構造体へのポインタを next に保存 p -> next = malloc(sizeof(struct list)); p = p -> next; p->next = NULL; printf("input=%s",input); } exit(0); } }

エラー
?「char」が構造または結合ではないのようなことが書いてあるが、どう改善したら良いか分からない。
? 構造体をつなげる部分をどうすれば良いのかよく分からない。

05.c:38:9: error: member reference base type 'char' is not a structure or union p -> next = malloc(sizeof(struct list)); ~ ^ ~~~~ 05.c:39:13: error: member reference base type 'char' is not a structure or union p = p -> next; ~ ^ ~~~~ 05.c:40:8: error: member reference base type 'char' is not a structure or union p->next = NULL; ~^ ~~~~ 3 errors generated.

よく分からないコードになってしまっているかと思いますが、
どうか温かい目でご教授お願い致します。

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

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

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

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

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

ccodereader

2022/05/14 05:10

その他で、あまりよく分からない部分です。余力があれば教えて頂けると嬉しいです。 ? MAXLINEでいいのかどうか。 ? printfの部分はこの場合、どのように書くのが正解かよく分からない。 ? char *p, *start;の部分で、*startは書かずにchar *pだけでもいいのかどうか。
dodox86

2022/05/14 06:02

理解していないのに最初から全て、完成形のコードを目指さない方がいいです。分からないところをひとつひとつ片付けましょう。
guest

回答2

0

ベストアンサー

※ 実装例として

c

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4#define MAXLINE 1024 5 6struct list { 7 struct list *next; 8 char *name; 9}; 10 11int main(){ 12 char input[MAXLINE]; 13 char *p = NULL; 14 struct list *q = NULL, *start = NULL; 15 16 for(;;){ 17 p = fgets(input, MAXLINE, stdin); 18 if (p == NULL) { 19 break; 20 } 21 22 if (q == NULL) { 23 q = (struct list *)malloc(sizeof(struct list)); 24 start = q; 25 } 26 27 int size = strcspn(input, "\n"); 28 q->name = (char *)malloc(size + 1); 29 strncpy(q->name, input, size); 30 q->name[size] = 0; 31 q->next = (struct list *)malloc(sizeof(struct list)); 32 q = q->next; 33 q->next = NULL; 34 } 35 36 if (start != NULL) { 37 for (q=start;q->next!=NULL;q=q->next) { 38 printf("input=%s\n", q->name); 39 } 40 } 41 42 exit(0); 43}

投稿2022/05/14 07:25

melian

総合スコア19703

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

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

ccodereader

2022/05/14 08:02

非常に分かりやすくありがとうございます!こちらを参考に少しずつ改善していきたいと思います! ご丁寧にありがとうございました!!
guest

0

char *p, *start;

p はcharのアドレス(ポインタ)になってますが、

p -> next = malloc(sizeof(struct list));

char にはnextというメンバはありません

その構造体のポインタにする必要があるんでは

投稿2022/05/14 05:13

編集2022/05/14 05:15
y_waiwai

総合スコア87747

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

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

ccodereader

2022/05/14 05:37

ありがとうございます。正しく変えられたかあまり自信はないのですが、以下に変更したところエラーがなくなりました!ありがとうございます。 ただ、入力時にenterを押すと続けて入力できず、Control-Dキーを押す段階まで行けません。可能であれば、その原因と解決策を教えて頂けると非常に助かります。どうぞよろしくお願い致します。 #include <stdio.h> #include <string.h> #include <stdlib.h> //1行入力のために用意するchar型の配列の大きさはマクロで定義し1024 #define MAXLINE 1024 //自己参照構造体を定義 struct list { struct list *next; char *name; }; int main(){ char input[MAXLINE]; //構造体型のポインタ char *p, *start; struct list *q; //forを使った繰返しの中でfgetsを使って単語を入力 for(;;){ p = fgets(input,MAXLINE,stdin); //pがNULLの時、入力の終了 if(p == NULL){ break; } p = strchr(input,'\n'); if(p != NULL){ //1回目のループ -- 先頭の構造体を生成 p = malloc(sizeof(struct list)); start = p; }else{ //2回目以降 -- 構造体へのポインタを next に保存 q -> next = malloc(sizeof(struct list)); q = q -> next; q->next = NULL; printf("input=%s",input); } exit(0); } }
y_waiwai

2022/05/14 05:44

コンパイルエラーがない、ってのはあくまで、コードの文法のエラーがない、ってだけのはなしなんで、そのコードが正しいってことにはなりません。 ってことで、自分のコードを読んでみましょう。 各変数それぞれ、なにが入っているのか、なにを入れなければならないのかってのをよく考えましょう まだまだバグが残ってます
ccodereader

2022/05/14 07:43

そうですよね、ご丁寧にありがとうございました。 少しずつ頑張っていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問