No.14626![]() |
ファイルポインタの使い方について 投稿者---ぶんお(2004/06/15 10:37:04) |
||
ファイルポインタを関数に渡して処理を実行しようとしています。 過去ログなどを参照してみたのですが、使い方について分からない ことがでてきました。 1. FILE *fp1,*fp2 と定義した場合、 渡す側が sub(&fp1,&fp2) ; 受け側が int sub(FILE **fp1,FILE **fp2) ; となるのですか。 2. fopenでファイルをオープン後(アドレスを確保後)は、 渡す側:sub(&fp1,&fp2) ; 受け側:int sub(FILE **fp1,FILE **fp2) または、 渡す側:sub(fp1,fp2) ; 受け側:int sub(FILE **fp1,FILE **fp2) のどちらでも可能なのでしょうか。 3.また、sub関数から、ポインタを再度、別関数に渡す場合は sub関数に渡された状況によりかわるのでしょうか。 int sub(FILE **fp1,FILE **fp2) { output(fp2,buff) ; または、 output(&(*fp2),buff) ; } int sub(FILE **fp1,FILE **fp2) { output(fp2,buf) ; } ソース #include <stdio.h> #include <string.h> #include <stdlib.h> int init_syori(FILE **,FILE **) ; int main_syori(FILE *,FILE *) ; int end_syori(FILE **,FILE **) ; void output(FILE *,char *,int *) ; main() { FILE *fp1,*fp2 ; int ret ; ret = init_syori(&fp1,&fp2) ; if (ret == 0) { main_syori(fp1,fp2) ; } end_syori(&fp1,&fp2) ; exit(0) ; } int init_syori(FILE **fp1,FILE **fp2) { if ((*fp1 = fopen("/tmp/read.txt","r")) == NULL) { printf("FileError: file open failed (%s)\n", "/tmp/read.txt") ; return(-1) ; } if ((*fp2 = fopen("/tmp/write.txt","w")) == NULL) { printf("FileError: file open failed (%s)\n", "/tmp/write.txt") ; return(-1) ; } return(0) ; } int main_syori(FILE *fp1,FILE *fp2) { char buff[256] ; int cnt = 0 ; while(fgets(buff,sizeof(buff),fp1) != NULL) { buff[strlen(buff)-1] = '\0' ; output(fp2,buff,&cnt) ; } printf("Reac cnt [%d]\n",cnt) ; } int end_syori(FILE **fp1,FILE **fp2) { fclose(*fp1) ; fclose(*fp2) ; return(0) ; } void output(FILE *fp2,char *buff,int *cnt) { fprintf(fp2,"%s\n",buff) ; (*cnt)++ ; } #include <stdio.h> #include <string.h> #include <stdlib.h> int init_syori(FILE **,FILE **) ; int main_syori(FILE **,FILE **) ; int end_syori(FILE **,FILE **) ; void output(FILE **,char *,int *) ; main() { FILE *fp1,*fp2 ; int ret ; ret = init_syori(&fp1,&fp2) ; if (ret == 0) { main_syori(&fp1,&fp2) ; } end_syori(&fp1,&fp2) ; exit(0) ; } int init_syori(FILE **fp1,FILE **fp2) { if ((*fp1 = fopen("/tmp/read.txt","r")) == NULL) { printf("FileError: file open failed (%s)\n", "/tmp/read.txt") ; return(-1) ; } if ((*fp2 = fopen("/tmp/write.txt","w")) == NULL) { printf("FileError: file open failed (%s)\n", "/tmp/write.txt") ; return(-1) ; } return(0) ; } int main_syori(FILE **fp1,FILE **fp2) { char buff[256] ; int cnt = 0 ; while(fgets(buff,sizeof(buff),*fp1) != NULL) { buff[strlen(buff)-1] = '\0' ; //output(&(*fp2),buff,&cnt) ; output(fp2,buff,&cnt) ; } printf("Read cnt [%d]\n",cnt) ; } int end_syori(FILE **fp1,FILE **fp2) { fclose(*fp1) ; fclose(*fp2) ; return(0) ; } void output(FILE **fp2,char *buff,int *cnt) { fprintf(*fp2,"%s\n",buff) ; (*cnt)++ ; } |
No.14627![]() |
Re:ファイルポインタの使い方について 投稿者---REE(2004/06/15 11:54:22) |
||
>ファイルポインタを関数に渡して処理を実行しようとしています。 >過去ログなどを参照してみたのですが、使い方について分からない >ことがでてきました。 これらの問題は、ファイルポインタに関わらず、ポインタ一般の話です。 >1. > FILE *fp1,*fp2 > と定義した場合、 > 渡す側が > sub(&fp1,&fp2) ; > 受け側が > int sub(FILE **fp1,FILE **fp2) ; > となるのですか。 受け側でfp1,fp2を変更して欲しい時にはそうします。 >2. > fopenでファイルをオープン後(アドレスを確保後)は、 > 渡す側:sub(&fp1,&fp2) ; > 受け側:int sub(FILE **fp1,FILE **fp2) > または、 > 渡す側:sub(fp1,fp2) ; > 受け側:int sub(FILE **fp1,FILE **fp2) → int sub(FILE *fp1,FILE *fp2) > のどちらでも可能なのでしょうか。 はい >3.また、sub関数から、ポインタを再度、別関数に渡す場合は > sub関数に渡された状況によりかわるのでしょうか。 例の違いがわかりませんが、一般的に、引数の渡し方は、渡すものの型と、引数の型で決まります。 |
No.14629![]() |
Re:ファイルポインタの使い方について 投稿者---ぶんお(2004/06/15 12:42:42) |
||
ありがとうございます。 1、2、3について、 そのようになる理由、解釈を教えて欲しいのですが。 3.また、sub関数から、ポインタを再度、別関数に渡す場合は sub関数に渡された状況によりかわるのでしょうか。 int sub(FILE **fp1,FILE **fp2) { output(fp2,buff) ; または、 output(&(*fp2),buff) ; } int sub(FILE *fp1,FILE *fp2) { output(fp2,buf) ; } 要は、ポインタのポインタなのか、ポインタの違いなのでしょうか。 |
No.14630![]() |
Re:ファイルポインタの使い方について 投稿者---REE(2004/06/15 13:55:41) |
||
普通は、関数の引数の型は、その関数の用途で決めます。 関数でint型の変数を参照するだけであれば、引数の型は、intにします。(int *にすることも出来ます) 関数でint型の変数を変更したいのであれば、引数の型は、int *にします。 関数でFILE *型の変数を参照するだけであれば、引数の型は、FILE *にします。(FILE **にすることも出来ます) 関数でFILE *型の変数を変更したいのであれば、引数の型は、FILE **にします。 関数への引数の渡す時は、渡したい変数をその関数の引数の型に合わせて渡します。 変数の型がint で関数の引数の型もint であれば、そのまま渡します。 変数の型がint で関数の引数の型がint *であれば、&をつけてint*型に変換して渡します。 変数の型がint *で関数の引数の型がint であれば、*をつけてint型に変換して渡します。 変数の型がint *で関数の引数の型もint *であれば、そのまま渡します。 変数の型がFILE * で関数の引数の型もFILE * であれば、そのまま渡します。 変数の型がFILE * で関数の引数の型がFILE **であれば、&をつけてFILE **型に変換して渡します。 変数の型がFILE **で関数の引数の型がFILE * であれば、*をつけてFILE *型に変換して渡します。 変数の型がFILE **で関数の引数の型もFILE **であれば、そのまま渡します。 |