C言語関係掲示板

過去ログ

No.1147 ファイルポインタの使い方について

[戻る] [ホームページ]
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 **であれば、そのまま渡します。