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

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

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

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

Q&A

解決済

2回答

3729閲覧

[C]関数で構造体配列の中身を表示させる際に、コンソールが停止

wAsabi1107

総合スコア11

C

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

0グッド

0クリップ

投稿2017/06/09 15:49

閲覧ありがとうございます。

  • 言語 : C
  • コンパイラ : gcc
  • コンソール : コマンドプロンプト

下記ソースをコンパイルし、実行すると、マークした行でコンソールが動作停止してしまいます。

C

1#include<stdio.h> 2 3/* 構造体 */ 4typedef struct{ 5 char name[60]; 6 short age; 7 char sex; 8}People; 9 10/* プロトタイプ宣言 */ 11void writeData(People data[]); /* 入力用の関数 */ 12void printData(People data[]); /* 出力用の関数 */ 13 14/* main関数 */ 15int main(void) 16{ 17 People data[3]; /* 構造体変数 */ 18 People *pdata; /* 構造体ポインタ変数 */ 19 20 pdata = data; /* ポインタにセット */ 21 22 writeData(pdata); /* 入力 */ 23 printData(pdata); /* 出力 */ 24 25 return 0; 26} 27 28/* 入力用の関数 */ 29void writeData(People data[]) 30{ 31 short cnt; 32 33 printf("3人の氏名、年齢、性別(0:男性 1:女性)を入力してください。 \n"); 34 for(cnt = 0; cnt < 3; cnt++) 35 { 36 printf("[%d人目] \n", cnt + 1); 37 printf("\t氏名 :", cnt);scanf("%s", data[cnt].name); 38 printf("\t年齢 :", cnt);scanf("%d", &data[cnt].age); 39 printf("\t性別 :", cnt);scanf("%d", &data[cnt].sex); 40 } 41 printf("◆入力完了 \n\n"); 42} 43 44/* 出力用の関数 */ 45void printData(People data[]) 46{ 47 short cnt; 48 49 printf("3人分のデータを出力します。 \n"); 50 for(cnt = 0; cnt < 3; cnt++) 51 { 52 printf("[%d人目] \n", cnt + 1); 53 printf("\t氏名 : %s \n", data[cnt].name); /* ◆この行を実行しようとすると動作停止 */ 54 printf("\t年齢 : %d \n", data[cnt].age); 55 if(data[cnt].sex == 0) 56 printf("\t性別 : 男性 \n"); 57 else 58 printf("\t性別 : 女性 \n"); 59 } 60} 61

コンソールが停止するだけでエラー表示も何もないので、対処方法が分かりません。
このバグの原因は何なのでしょうか?ご教示いただけると幸いです。

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

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

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

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

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

guest

回答2

0

Chironian さんのおっしゃる通り、sex は char 型なのでscanf("%d"で入力するには領域が足らず、関係ないところにも上書きしてしまいます。 writeData() で使っている data の実体は、以下のように main() で定義されている data ですので、すぐ下に定義してある pdata を上書きして壊しているのだと思います。

C

1 People data[3]; /* 構造体変数 */ 2 People *pdata; /* 構造体ポインタ変数 */

つまり、writeData() で pdata を壊してしまい、printData() に渡すときには pdata の中身はデタラメなものになっているのでしょう。

投稿2017/06/09 17:10

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

wAsabi1107

2017/06/10 00:22

なるほど、メモリ領域の破壊がコンソールの停止する理由なのですね。 分かりやすい解説ありがとうございます。
guest

0

ベストアンサー

こんにちは。

取り敢えず危険な部分が2箇所あります。
scanf("%d"で読み出先はint型変数です。しかし、ageとsecはそれぞれshortとcharですので領域が足りません。
しかし、ここで落ちず、更に先で落ちているのは不可解です。

取り敢えず、ageとsecをint型とし、一部のprintf文の余分なcntを削除して下記を入力してみました。

abc 21 0

def 22 1
ghi 23 0

特に問題なく動作しました。wandbox

入力データの相違だろうと思います。どんなデータを入力されたでしょうか?

投稿2017/06/09 16:12

Chironian

総合スコア23272

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

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

wAsabi1107

2017/06/10 00:33

回答ありがとうございます! 手元の環境でもご指摘いただいた箇所を修正し(sexをshort型に、scanf関数の変換指定子を%dから%hdに)、無事動作しました。 こちら修正前ソースでの実行結果と、入力データですhttps://wandbox.org/permlink/PSiIkbzLizJWWQpo なぜか動作していますが・・・笑(変換指定子の警告が出ているので、そこを上手く調整してくれた?) hideki1234さんのご指摘にあるように、メモリ領域を破壊された構造体を呼び出そうとしたので動作停止というバグとなったのではないか、と愚考します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問