別の関数で fread() したいので、閉じずに残した init 関数で fopen で開いたファイルがあります。これを行うには、すべての関数がやり取りできるグローバルな静的ファイルを宣言しますか?
3 に答える
いいえ; ファイル ポインタをパラメータとして関数に渡します。
例えば:
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 );
...
}
理想的には、関数はパラメーター、戻り値、および例外 (利用可能な場合) を介して通信する必要があります。グローバル変数を介して状態を共有すると、メンテナンスの問題が発生します。
翻訳単位スコープの変数 (つまり a static FILE *
) を介してファイルを渡すことは許容されます。ただし、誰が を呼び出す責任があるかについては、いくつかの疑問が残りfclose
ます。より良いアプローチはFILE*
、呼び出し元が後で を呼び出すことを前提として、ファイルを開く関数を呼び出し元に返すことfclose
です。
さらに良いことに、ファイルを開く代わりに、呼び出す関数fread
もfopen
: を実行できるようにします。最初の関数でファイル名を準備し、それをstatic
変数に格納できます。次に、読み取り関数は、 を呼び出しfopen
、 を実行し、すべてを 1 つの関数でfread
呼び出すことができます。fclose
FILE*
それは、返される必要があるスコープによって異なりfopen()
ます。でファイルを開くとmain()
、ファイル ポインタを入力パラメータとして他の関数に渡し続けることができます。何かのようなもの:
int main ( void )
{
FILE *pFile = fopen ( ... );
// validate pFile
SomeFunc ( pFile );
...
fclose ( pFile );
}
void SomeFunc ( FILE *pF )
{
...
fread ( ... );
...
}
なんらかの理由で本当に必要でない限り、私はファイル ポインターをグローバル変数として宣言しません。グローバル変数を正しくクリーンアップするのを忘れがちで、大規模なプログラムでは変数のライフ サイクルを確認するのが難しくなります。
最善のアプローチは、ファイルのスコープをできるだけ狭く保つことです。これにより、コードの読み取りと保守が容易になり、リソースをより早く解放できます。