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

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

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

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

Q&A

解決済

2回答

663閲覧

C言語 構造体ポインタ配列の表示、処理落ちについて

samusunn36

総合スコア13

C

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

0グッド

1クリップ

投稿2019/04/19 12:27

編集2019/04/19 13:58

前提・実現したいこと

構造体を定義し、構造体のポインタ配列のメモリを確保する。
そのあと、構造体ポインタ配列の要素を入力から出力し、まとめて表示する。

発生している問題・エラーメッセージ

入力したものがうまく表示されない

該当のソースコード

C

1(#)include <stdio.h> 2(#)include <stdlib.h> 3(#)define NUM 3 4(#)define NUM1 20 5 6struct result { 7 int number; 8 char name[NUM1]; 9 int english; 10}; 11 12int main(void) { 13 struct result *s_rt[NUM]; 14 15 int i; 16 for (i = 0; i < NUM; i++) { 17 s_rt[i] = (result*)malloc(sizeof(result)); 18 if (s_rt[i] == NULL) 19 printf("メモリの動的確保に失敗しました\n"); 20 21 else { 22 printf("%d番目の番号を入力してください:", i + 1); 23 scanf_s("%d", &s_rt[i]->number); 24 printf("%d番目の名前を入力してください:", i + 1); 25 scanf_s("%s", s_rt[i]->name, NUM1); 26 printf("%d番目の英語の点数を入力してください:", i + 1); 27 scanf_s("%d", &s_rt[i]->english); 28 } 29 free(s_rt[i]); 30 } 31 int j; 32 for (j = 0; j < NUM; j++) { 33 printf("番号:%d\n", s_rt[j]->number); 34 printf("名前:%s\n", s_rt[j]->name); 35 printf("英語の点数:%d\n", s_rt[j]->english); 36 } 37 return 0; 38}

試したこと

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

1番目の番号を入力してください:1
1番目の名前を入力してください:a
1番目の英語の点数を入力してください:1
2番目の番号を入力してください:4
2番目の名前を入力してください:b
2番目の英語の点数を入力してください:2
3番目の番号を入力してください:5
3番目の名前を入力してください:c
3番目の英語の点数を入力してください:3
番号:-572662307
名前:ンンンンンンンンンンンンンンンンンンンンンンンンンンンン
英語の点数:-572662307
番号:-572662307
名前:ンンンンンンンンンンンンンンンンンンンンンンンンンンンン
英語の点数:-572662307
番号:-572662307
名前:ンンンンンンンンンンンンンンンンンンンンンンンンンンンン・ン
英語の点数:-572662307

文字化けが起きてしまう

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

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

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

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

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

otn

2019/04/19 12:33

せめて、コンパイルが通るコードを書きましょう。 コードは、 ```C と ``` の間に書いてください。
samusunn36

2019/04/19 12:36

ご返答ありがとうございます このサイトを始めたのがついさっきだったもので、あまり慣れていませんでした。申し訳ないです。 コンパイルはCです。
otn

2019/04/19 12:41

サイトの使い方の話はさておき、まずあなたが実行したというコンパイルが通るコードを書かないと話が始まりません。
samusunn36

2019/04/19 12:46

上に載せたソースコードとは別のコードですか?
otn

2019/04/19 12:51

はい。あなたが実行したというコンパイルが通るコードです。
mather

2019/04/19 12:55

「処理落ち」とは実行時エラーのことでしょうか。 エラーが発生しているときは実行時のエラーメッセージも質問に記載しましょう。 質問は編集できるので、ここに返信するのではなく追記をしてくださいね。
samusunn36

2019/04/19 12:59

コンパイルが通るコードとは、何なのでしょうか。 プログラミング初心者でかつ、馬鹿なのでそこら辺のことを理解できていないです。申し訳ないです。教えていただけないでしょうか。
mather

2019/04/19 13:02

コンパイルってわかりますか?gccとか。
samusunn36

2019/04/19 13:03

>matherさん ご返答ありがとうございます。 実行し、キーボードから入力している途中、2番目の番号を入力した後に画面が止まってしまいます。 いつも出るようなエラー表示が出ないため困っている状態です。
otn

2019/04/19 13:04

> コンパイルが通るコードとは、 コンパイルエラーが出ずにコンパイルできるプログラムという意味です。 というか、コンパイルエラーの出るでたらめなプログラムじゃなくて、あなたが実行したというプログラムを書いてください。 そもそも、「コンパイル」がわかりませんか?
mather

2019/04/19 13:06

「いつも出るような」は私達にとってはわからないので、入力時に表示される部分("1番目の番号を入力してください:" などの部分)も含めて画面に出力されるものを全部見せてください。
cateye

2019/04/19 13:22 編集

scanf()またはscanf_s()は癖の有る関数です。scanf()はセグメントフォルト、scanf_s()は入りきれない文字を入力バッファに残したままになります。気をつけましょう。出来れば、fgets()とsscanf()を組み合わせて使うほうがいいと思います。 ちなみに2回めというのは、scanf_s("%d", &s_rt[i]->number);のs_rt[1]のアドレスがゴミだから固まる(処理系によって変わる)ですが・・・
episteme

2019/04/19 13:13

えーと、"処理落ち"とは処理速度がガタ落ちすることであって、"処理が停止する"じゃないからね?
mather

2019/04/19 13:27

まるっとコピーしてください。 質問に書かれているソースコードでは「英語の点数」になっているのに、追記されたものでは「点数」になってますよ? どっちが正しく、最新の情報なのでしょうか。
samusunn36

2019/04/19 13:50

皆さん、ご返答ありがとうございます!
cateye

2019/04/19 15:51 編集

scanf_s("%s", s_rt[i]->name, NUM1);の記述がおかしい? →scanf_s("%s", &s_rt[i]->name, NUM1); ↑ミスです。忘れて下さいmm
guest

回答2

0

s_rt[0] = (result*)malloc(sizeof(result));

配列の最初の項目分しか、領域が確保されていません。
従って、s_rt[0] は、有りますが、 s_rt[1] 以降の領域がありません。

ところで、エラーメッセージはどうなっていたでしょうか?
結構、エラーメッセージで検索かける答えが分かる場合がありますね。

投稿2019/04/19 12:42

pepperleaf

総合スコア6383

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

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

samusunn36

2019/04/19 12:53

ご返答ありがとうございます。 領域確保の部分を0からNUMに変えてみたところ、1番目の番号を入力した時点で処理落ちするようになりました。 エラーメッセージが表示されずに落ちてしまいます。プログラミングの書いてある部分には「例外がスローされました」と表示されています。
cateye

2019/04/19 13:08

3個確保するならそれなりの処理が必要です。・・・要は、3回確保しなければならないはずですが?
guest

0

ベストアンサー

気になった所:struct result *s_rt[NUM];の後の処理はループの中に入れましょう。また、free(s_rt);では、メモリの開放は出来ません。個別(free(s_rt[0]);)にしましょう。
「追記」ほぼ完成してるようなので、参考までに。

c

1#include <stdio.h> 2#include <stdlib.h> 3// 4#define NUM 3 5#define NUM1 20 6// 7struct result { 8 int number; 9 char name[NUM1]; 10 int english; 11}; 12// 13int main(void) 14{ 15 struct result *s_rt[NUM]; 16 for (int i = 0; i < NUM; i++) { 17 s_rt[i] = (struct result *)malloc(sizeof(struct result)); 18 if (s_rt[i] == NULL) { 19 printf("メモリの動的確保に失敗しました\n"); 20 if (i != 0) { 21 for (int j = 0; j < i; j++) { 22 free(s_rt[j]); 23 } 24 } 25 exit(1); 26 } else { 27 printf("%d番目の番号を入力してください:", i + 1); 28 scanf("%d", &s_rt[i]->number); 29 printf("%d番目の名前を入力してください:", i + 1); 30 scanf("%s", s_rt[i]->name); 31 printf("%d番目の英語の点数を入力してください:", i + 1); 32 scanf("%d", &s_rt[i]->english); 33 } 34 } 35 // int j; 36 for (int i = 0; i < NUM; i++) { 37 printf("番号:%d\n", s_rt[i]->number); 38 printf("名前:%s\n", s_rt[i]->name); 39 printf("英語の点数:%d\n", s_rt[i]->english); 40 free(s_rt[i]); 41 } 42 putchar('\n'); 43 44 return 0; 45}

結果

text

1usr ~/Project/test/teratail % ./a.out 21番目の番号を入力してください:2 31番目の名前を入力してください:aaa 41番目の英語の点数を入力してください:123 52番目の番号を入力してください:4 62番目の名前を入力してください:bbbbbbbb 72番目の英語の点数を入力してください:456 83番目の番号を入力してください:5 93番目の名前を入力してください:dd 103番目の英語の点数を入力してください:789 11番号:2 12名前:aaa 13英語の点数:123 14番号:4 15名前:bbbbbbbb 16英語の点数:456 17番号:5 18名前:dd 19英語の点数:789 20 21usr ~/Project/test/teratail %

投稿2019/04/19 13:31

編集2019/04/19 14:07
cateye

総合スコア6851

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

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

cateye

2019/04/19 13:34

if (s_rt == NULL)もアドレス判定にはなりません。
samusunn36

2019/04/19 14:30

プログラミングを完成させることができました。 未熟な私に、懇切丁寧に教えていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問