- ベストアンサー
main関数をスッキリさせるための関数化の方法
- main関数をスッキリさせるために、関数化してみましたが、実行ファイルができません。
- エラー内容は、'関数'を'FILE *'に変換できないというものです。
- 正しい書き方を教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
以下のようにしてください。 方法1 red_fの戻り値でf_pを返すようにする ---------------------------------- #include <stdio.h> #include <stdlib.h> FILE *read_f(void); void output_f(FILE *f_p); int main(void){ FILE *fp; fp = read_f(); output_f(fp); fclose(fp); return 0; } FILE *read_f(void){ int fn=0; FILE *f_p; char f_name[256]; printf(" text number 1, 2, 3, 4 : "); scanf("%d",&fn); sprintf(f_name,"map%d.txt",fn); if((f_p=fopen(f_name,"r"))==NULL){ /*f_nameを " " で囲まない!*/ printf("You will not be able to open the file\n"); exit(1); } return f_p; } void output_f(FILE *f_p){ int i,j; int array[10][10]; for(j=0;j<10;j++){ for(i=0;i<10;i++){ fscanf(f_p,"%d",&array[i][j]);//画面表示 10*10 printf("%d",array[i][j]); } } printf("\n"); } ----------------------------------------------------- 方法2 read_fの出力パラメータでf_pを返すようにする ---------------------------------------------------- #include <stdio.h> #include <stdlib.h> void read_f(FILE **f_p); void output_f(FILE *f_p); int main(void){ FILE *fp; read_f(&fp); output_f(fp); fclose(fp); return 0; } void read_f(FILE **f_p){ int fn=0; char f_name[256]; printf(" text number 1, 2, 3, 4 : "); scanf("%d",&fn); sprintf(f_name,"map%d.txt",fn); if((*f_p=fopen(f_name,"r"))==NULL){ /*f_nameを " " で囲まない!*/ printf("You will not be able to open the file\n"); exit(1); } } void output_f(FILE *f_p){ int i,j; int array[10][10]; for(j=0;j<10;j++){ for(i=0;i<10;i++){ fscanf(f_p,"%d",&array[i][j]);//画面表示 10*10 printf("%d",array[i][j]); } } printf("\n"); } ------------------------------------------------------ どちらでも問題ありませんが、方法1のほうが理解しやすいので、そちらを推奨します。 なお、printf("%d",array[i][j]);の位置が誤っていますので、正しい位置に修正してあります。
その他の回答 (3)
- wormhole
- ベストアンサー率28% (1626/5665)
コンパイルエラーを直すだけなら#1,#2の方のいわれる通りですが、それだけではまともに動かないです。 そのコードだとread_f内で行っているfopenの戻り値はmain関数には渡りません。
お礼
解答ありがとうございます。 もう、頭が回転しません。main関数の中をスッキリさせる事が本題だったので、 逃げになるのですが、合体させてしまいました。<(_ _)> #include <stdio.h> #include <stdlib.h> void read_out_f(void); int main(void){ read_out_f(); return 0; } void read_out_f(){ FILE *f_p; int fn=0; int i,j; int array[10][10]; char f_name[256]; printf(" map number 1, 2, 3, 4 : "); scanf("%d",&fn); sprintf(f_name,"map%d.txt",fn); if((f_p=fopen(f_name,"r"))==NULL){ /*f_nameを " " で囲まない!*/ printf("You will not be able to open the file\n"); exit(1); } for(j=0;j<10;j++){ for(i=0;i<10;i++){ fscanf(f_p,"%d",&array[i][j]); //画面表示 10*10 printf("%d",array[i][j]); } printf("\n"); } fclose(f_p); } どうやって、ファイルポインタの値を渡したらいいか思いつきませんでした
- mitojii2
- ベストアンサー率0% (0/1)
修正点はNo.1さんのご指摘どおりですが、 質問者の方はポインタの概念の把握がまだ曖昧なご様子なので蛇足を。 4行目 void read_f(FILE *f_p); のプロトタイプ宣言は >関数read_fは「FILE *」型のパラメータを持ち、返数を持たない って意味ですよね? そして8行目 FILE *fp; では >fpは「FILE *」型のローカル変数である と宣言している訳で [fpが保持しているアドレス]-->[FILE構造体領域] てな構図な訳です ので、9、10行目はアドレスのみ引き渡しのため*無しが正解と 要するに*はアドレスをたどるジャンプの数と思えばいいので 変数ラベルの一部ではありませんってのが簡単かと FILE ****fp; なら [fpが保持しているアドレス]-->[アドレス]-->[アドレス]--> [アドレス]-->[FILE構造体領域] ちなみに私の個人的流儀では、宣言時の*とラベルの間には空白を置きます int tatoeba(int, char, FILE **); /* prototype sample */ FILE **** fp; /* data saple */ プロトタイプではラベルも省略しちゃいます(^_^;) あ、もちろん実行時のラベル参照では*とラベルの間に空白いれちゃダメですよ
お礼
解答ありがとうございます。 簡単な関数を作って実験してみます。 あと、「要するに*はアドレスをたどるジャンプの数と思えばいい」 のところ、目から鱗です。 なるほどっておもいました。
- BuriBuri4
- ベストアンサー率28% (150/525)
× read_f(*fp); × output_f(*fp); ○ read_f(fp); ○ output_f(fp);
お礼
簡潔な解答ありがとうございます。 ポインタむずかしい・・・
お礼
2パターンも書いていただき感謝です。 これらをよく見て、ポインタの動きを勉強しなおします。 ありがとうございました。