• ベストアンサー

構造体の構造体 引数

構造体の中の構造体の関数の引き渡し方法がわかりません。 下記ソースで試したのですが、うまくいきませんでした。 助言お願いいたします。 //repo.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define NUM 20 #define MAX 15 struct seiseki{ float shu[3]; }; struct seito{ char name[NUM]; int age; struct seiseki kekka; }; void input(struct seito *p); void s_input(struct seiseki *p); void ss_input(struct seiseki *data); int main(){ int i; struct seito data[2]; for(i=0;i<2;i++){ printf("------------------------------\n"); printf("%d人目",i+1); input(&data[i]); } printf("%f\n",data[0].kekka.shu[0]); printf("%f\n",data[0].kekka.shu[1]); printf("%f\n",data[0].kekka.shu[2]); //data[1]に格納できない。 printf("%f\n",data[1].kekka.shu[0]); printf("%f\n",data[1].kekka.shu[1]); printf("%f\n",data[1].kekka.shu[2]); return 0; } void input(struct seito *p){ printf("名前->"); scanf("%s",p->name); printf("年齢->"); scanf("%d",p->age); s_input(&(p->kekka)); } void s_input(struct seiseki *data){ printf("国語->"); ss_input(data); printf("算数->"); ss_input(data); printf("英語->"); ss_input(data); } //下記関数で成績をchar型で受け取り、数値化したい。 void ss_input(struct seiseki *data){ char p[100]; int i=0; static int o=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("再入力してください"); scanf("%s",p); } i++; } data->shu[o]=atof(p); printf("%f\n",data->shu[o]); o++; }

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

>第2引数おかしいでしょうか。よくわかっておりません。 セ->ageに入っている『未初期化の値をアドレスとみなし』、そこに入力結果を書き込むのが想定する動作ですか? p->ageには入力した値は入らないことになります。 >oは、seisekiのshu配列の要素番号に当てているつもりです。 ss_input()でoをprintf()で出力してみて下さい。 data[1]以降の場合に期待する値にならないはずです。 結果としては、バッファオーバーフローしてどこかの領域破壊しています。 oが0になるのは『最初の1回だけ』です。 static intですから、『関数を抜けた後もoの値は保存され』ます。 さて、誰がshu[0]を指すように戻しているのでしょうか? こういう場合、要素番号も引数として渡すか、ss_input()の戻り値をfloatにして呼び出し側で構造体に格納すべきです。 戻り値で返す場合、エラーだった場合の返却値が問題になりますが。

prg_test
質問者

お礼

ありがとうございました。 構造体を全然わかっていませんで3日間位悩んでました。しかし教えていただきうまくプログラムが周り構造体の勉強をもっと深くしようと意欲が湧きました! ほんとにありがとうございました!

prg_test
質問者

補足

ありがとうございます。 ss_input()の戻り値をfloatにして呼び出し側で構造体に格納すると、うまく格納できました! p->ageに入力結果を書き込むのを想定してます。 理解できました。間違っていました! printf("年齢->"); scanf("%d",&p->age)); で、良いでしょうか。

その他の回答 (2)

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.3

>セ->ageに入っている『未初期化の値をアドレスとみなし』、そこに入力結果を書き込むのが想定する動作ですか? 下記に訂正。(見直し漏れ) p->ageに入っている『未初期化の値をアドレスとみなし』、そこに入力結果を書き込むのが想定する動作ですか?

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

問題点2つ。 1)input関数 >printf("年齢->"); >scanf("%d",p->age); scanfの第2引数は正しいでしょうか? 2)ss_input関数で、oの値はどのように変化するでしょうか?

prg_test
質問者

補足

第2引数おかしいでしょうか。よくわかっておりません。 アドバイスお願いします。 oは、seisekiのshu配列の要素番号に当てているつもりです。 下記テストをしてみました。 1人目名前->tes 年齢->6 国語->50 算数->80 英語->90 ----------------- 2人目名前->tes2 年齢->12 国語->100 算数->75 英語->70 で入力して、下記プリントした場合、 printf("%f\n",data[0].kekka.shu[0]); printf("%f\n",data[0].kekka.shu[1]); printf("%f\n",data[0].kekka.shu[2]); printf("%f\n",data[1].kekka.shu[0]); printf("%f\n",data[1].kekka.shu[1]); printf("%f\n",data[1].kekka.shu[2]); static int o=0; 50.000000 80.000000 90.000000 0.000000 0.000000 0.000000 int o=0; 50.000000 0.000000 0.000000 100.000000 0.000000 0.000000

関連するQ&A

専門家に質問してみよう