- ベストアンサー
構造体の自作関数内で入力した値の返し方
こんばんはm(_ _)m C言語の構造体に関する質問です。 (当方初心者なので用語等見苦しい点があると思いますがご了承&指摘をお願いします。) 日付を元号に直したりする構造体のプログラムでmain関数ではなく自作関数内で値を入力する問題を解いていまして… #include<stdio.h> typedef struct{ int year; int month; int day; }date; date put_date(date x) /*ここで日付を入力*/ { date x; printf("年:"); scanf("%d",x.year); printf("月:″); scanf("%d",x.month); printf("日:"); scanf("%d",x.day); return x; } int main(void) { date x; x.year=0; /*問題では関数外で宣言した変数では足りないため に他の自作関数で変数を使いまわすために必要な処 理で初期化しました。*/ put_date(x); gen(x); /*西暦の日付を元号で表す自作関数でここへput_date で取得したx,y,zを送りたいのですがmainに来た時点 でput_dataで入力した値が出ませんでした。(元号に 直す関数は省略いたしました)*/ } put_date内でprintfしましたところx,y,zの値が入力した通りに出ましたが、main内ではx.year=0,x.month=12,x.day=0という値になってしまいます。 put_dateで入力した値をmain関数内だけでなく他の自作関数内でも使用したいのですがどうすればよろしいでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
put_date内でprintfしましたところx,y,zの値が入力した通りに出ましたが、main内ではx.year=0,x.month=12,x.day=0という値になってしまいます。 と言うことは実行できたのですよね? 提示されたコードを見る限り、 コンパイルが通らない気がしますが、 実行されたコードと違うのではありませんか? date put_date(date x) { date x;//xはもう存在する printf("年:"); scanf("%d",x.year);//これではyearに値は入らない printf("月:″); scanf("%d",x.month); printf("日:"); scanf("%d",x.day); return x; } date put_date(date x) この定義を変えられないのは本当ですか? 問題の内容はMain関数のdate構造体xを使いまわさなければ ならないのですよね? もしそうなら、date put_date(date x)では Main のdate x を使いまわすのは不可能です。 もう一度問題を正確に!
その他の回答 (4)
- yaemon_2006
- ベストアンサー率22% (50/220)
"return x" してるんだから、main関数内でそれを受け取ればいいだけ。 #include <stdio.h> typedef struct{ int year; int month; int day; }date; date put_date(void) /*ここで日付を入力*/ { date x; printf("年:"); scanf("%d",&x.year); printf("月:"); scanf("%d",&x.month); printf("日:"); scanf("%d",&x.day); return x; } int main(void) { date x; ・・・ x = put_date();/* 戻り値を受け取る */ ・・・ gen(x); return 0; }
- lv4u
- ベストアンサー率27% (1862/6715)
No.1さんの回答のように、グローバルに取るという方法もあるのですが、通常は、禁じ手にされることが多いので、No.2さんの回答にあるように、構造体をアドレス渡しにしてみました。ただ問題の箇所がほかにもあるので(scanf時にアドレスエラーで落ちる)、6行ほど手直ししました。 C++であれば、リファレンス引数が使えて楽なんですが、Cの場合は、アドレス渡しをしないと、呼び出し側に値を返せないので、ちょっと不便ですね。まあ、それでもJavaにくらべれば、ずっとやり易いのですが。 void put_date(date* x) // (1)構造体をアドレスで受ける { // date x; // (2)あるとコンパイルエラーになる printf("年:"); scanf("%d",&x->year); // (3)scanfの変数はアドレス printf("月:"); scanf("%d",&x->month); // (4) printf("日:"); scanf("%d",&x->day); // (5) return; } int main(void) { date x; x.year=0; put_date(&x); // (6)構造体をアドレスで渡す }
お礼
早速の回答ありがとうございますm(_ _)m プログラムのほうは仕事で覚えています。 会社から一切のデータを持ち出し禁止なので明日 A:グローバルにする B:アドレスで渡す をやってみます。 回答感謝の極みですm(_ _)m
- asuncion
- ベストアンサー率33% (2127/6289)
main()で定義したdate型の変数xへのポインタを put_date()に渡す方法があります。 もちろん、この場合は引数の型などを適切に変更しなければなりません。 関数の名前も、入力なのだから例えばget_date()あたりの方が 「名は体を表わす」ようになっていると思います。 put_date()だと、どうも「日付を出力する」ように思えてしまって…。
- tatsu99
- ベストアンサー率52% (391/751)
date x;をどの関数からでもみれるところに、おけば良いです。 #include<stdio.h> typedef struct{ int year; int month; int day; }date; date x; /* ここにおいて下さい*/ date put_date(date x) /*ここで日付を入力*/ -------------------------------- 上記のようにすることで、date xはどこからでも参照できるようになります。
お礼
おはようございます グローバルにしてコンパイルした結果 error: syntax error before "x" warning: data definition has no type or storage class と返されてしまいました。 アドレスにしてみましたが error: request for member `year' in something not a structure or union と日付を表示する関数の箇所にこのようなエラーが複数でました。 No.4さんの方法でコンパイルしてみましたが x=put_date();の行に error: too few arguments to function `put_date' と出てしまいました。 (あと問題ではdate put_date(date x) とあるので ここは変化できません・・・ ポインタ使えないのでしょうか・・・)