2

別の関数で fread() したいので、閉じずに残した init 関数で fopen で開いたファイルがあります。これを行うには、すべての関数がやり取りできるグローバルな静的ファイルを宣言しますか?

4

3 に答える 3

2

いいえ; ファイル ポインタをパラメータとして関数に渡します。

例えば:

FILE *init( char *fname )
{
  FILE *fp = fopen( fname, "r" );
  return fp;
}

void read( FILE *fp )
{
  ...
  while ( fread( buffer, sizeof buffer, 1, fp ))
    // do stuff
}

int main( void )
{
  FILE *fp = NULL;
  ...
  fp = init( "myfile.txt" );
  if ( fp )
    read( fp );
  ...
}

理想的には、関数はパラメーター、戻り値、および例外 (利用可能な場合) を介して通信する必要があります。グローバル変数を介して状態を共有すると、メンテナンスの問題が発生します。

于 2013-06-14T02:56:09.657 に答える
1

翻訳単位スコープの変数 (つまり a static FILE *) を介してファイルを渡すことは許容されます。ただし、誰が を呼び出す責任があるかについては、いくつかの疑問が残りfcloseます。より良いアプローチはFILE*、呼び出し元が後で を呼び出すことを前提として、ファイルを開く関数を呼び出し元に返すことfcloseです。

さらに良いことに、ファイルを開く代わりに、呼び出す関数freadfopen: を実行できるようにします。最初の関数でファイル名を準備し、それをstatic変数に格納できます。次に、読み取り関数は、 を呼び出しfopen、 を実行し、すべてを 1 つの関数でfread呼び出すことができます。fclose

于 2013-06-14T02:52:08.893 に答える
1

FILE*それは、返される必要があるスコープによって異なりfopen()ます。でファイルを開くとmain()、ファイル ポインタを入力パラメータとして他の関数に渡し続けることができます。何かのようなもの:

int main ( void )
{
    FILE *pFile = fopen ( ... );

    // validate pFile

    SomeFunc ( pFile );

    ...

    fclose ( pFile );
}

void SomeFunc ( FILE *pF )
{
    ...

    fread ( ... );

    ...
}

なんらかの理由で本当に必要でない限り、私はファイル ポインターをグローバル変数として宣言しません。グローバル変数を正しくクリーンアップするのを忘れがちで、大規模なプログラムでは変数のライフ サイクルを確認するのが難しくなります。

最善のアプローチは、ファイルのスコープをできるだけ狭く保つことです。これにより、コードの読み取りと保守が容易になり、リソースをより早く解放できます。

于 2013-06-14T02:55:02.237 に答える