チョコミントアイス

main関数をスッキリさせたくて、関数化してみたのですが、objファイルまではできるのですが実行ファイルができません。
エラー内容ですが、下のようにでます。
/*
test_2.c(9) : error C2440: '関数' : 'FILE' から 'FILE *' に変換できません。
test_2.c(9) : warning C4024: 'read_f' : の型が 1 の仮引数および実引数と異なります。
test_2.c(10) : error C2440: '関数' : 'FILE' から 'FILE *' に変換できません。
test_2.c(10) : warning C4024: 'output_f' : の型が 1 の仮引数および実引数と異なります。
*/

書き方が間違ってるとは思うのですが、どこをどう直せばいいかわかりません。
教えてください。

#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");
}

A 回答 (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]);の位置が誤っていますので、正しい位置に修正してあります。
    • good
    • 0
この回答へのお礼

2パターンも書いていただき感謝です。
これらをよく見て、ポインタの動きを勉強しなおします。
ありがとうございました。

お礼日時:2014/11/16 18:33

コンパイルエラーを直すだけなら#1,#2の方のいわれる通りですが、それだけではまともに動かないです。


そのコードだとread_f内で行っているfopenの戻り値はmain関数には渡りません。
    • good
    • 0
この回答へのお礼

解答ありがとうございます。
もう、頭が回転しません。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);
}

どうやって、ファイルポインタの値を渡したらいいか思いつきませんでした

お礼日時:2014/11/16 12:32

修正点は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 */
プロトタイプではラベルも省略しちゃいます(^_^;)
あ、もちろん実行時のラベル参照では*とラベルの間に空白いれちゃダメですよ
    • good
    • 0
この回答へのお礼

解答ありがとうございます。
簡単な関数を作って実験してみます。
あと、「要するに*はアドレスをたどるジャンプの数と思えばいい」
のところ、目から鱗です。
なるほどっておもいました。

お礼日時:2014/11/16 12:21

× read_f(*fp);


× output_f(*fp);

○ read_f(fp);
○ output_f(fp);
    • good
    • 0
この回答へのお礼

簡潔な解答ありがとうございます。
ポインタむずかしい・・・

お礼日時:2014/11/16 12:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報