および関数はfseek、ftellどちらも ISO C 言語標準によって定義されています。
以下は、2011 C 規格の最新のパブリック ドラフトからのものですが、1990、1999、および 2011 の ISO C 規格は、同一ではないにしても、この分野ではすべて非常に似ています。
7.21.9.4:
ftell関数は、 stream が指すストリームのファイル位置標識の現在の値を取得します。バイナリ ストリームの場合、値はファイルの先頭からの文字数です。テキスト ストリームの場合、そのファイル位置インジケータには未指定の情報が含まれます。この情報は、ストリームのファイル位置インジケータをftell呼び出し時の位置に戻すために
fseek関数で使用できます。このような 2 つの戻り値の差は、必ずしも、読み書きされた文字数の意味のある尺度ではありません。
7.21.9.2:
fseek関数は、 streamが指すストリームのファイル位置インジケーターを設定します。読み取りエラーまたは書き込みエラーが発生した場合、ストリームのエラー インジケータが設定され、fseekは失敗します。
バイナリ ストリームの場合、ファイルの先頭からの文字数で測定された新しい位置は、whenceで指定された位置にオフセットを追加することによって取得されます。whenceがSEEK_SETの場合、指定された位置はファイルの先頭、SEEK_CURの場合はファイル位置指示子の現在の値、またはSEEK_ENDの場合はファイルの終わりです
。バイナリ ストリームは、 whence値がSEEK_ENDであるfseek呼び出しを意味のある形でサポートする必要はありません。
テキスト ストリームの場合、offsetはゼロであるか、offsetは同じファイルに関連付けられたストリームで以前に成功したftell関数
の呼び出しによって返された値であり、
whereceはSEEK_SETです。
「shall」句のいずれかに違反すると、プログラムの動作が未定義になります。
そのため、ファイルがバイナリ モードで開かれた場合、ファイルftellの先頭からの文字数が表示されますが、fseekファイルの末尾からの相対値 ( SEEK_END) は必ずしも意味のあるものではありません。これは、バイナリ ファイルをブロック全体に格納し、最終ブロックに書き込まれた量を追跡しないシステムに対応します。
ファイルがテキスト モードで開かれた場合、オフセット 0 を使用してファイルの先頭または末尾をシークするか、以前の への呼び出しで指定された位置をシークできますftell。fseek他の引数を使用した場合の動作は未定義です。これは、テキスト ファイルから読み取られる文字数がファイル内のバイト数と必ずしも一致しないシステムに対応します。たとえば、Windows で CR-LF ペア ( "\r\n") を読み取ると、1 文字しか読み取れませんが、ファイル内で 2 バイト進みます。
実際には、Unix ライクなシステムでは、テキスト モードとバイナリ モードは同じように動作し、fseek/ftell メソッドが機能します。Windowsでも動作すると思います(私の推測では、バイトオフセットが得られますが、これはテキストモードでftell呼び出すことができる回数と同じではない可能性があります)。getchar()
ftell()type の結果を返すことにも注意してくださいlong。が 32 ビットのシステムでlongは、この方法は 2 GiB 以上のファイルには使用できません。
ファイルのサイズを取得するには、システム固有の方法を使用する方がよい場合があります。とにかく fseek/ftell メソッドはstat()、Unix ライクなシステムなど、システム固有であるためです。
一方、fseekおよびは、遭遇する可能性が高いほとんどのftellシステムで期待どおりに機能する可能性があります。それが機能しないシステムがあると確信しています。申し訳ありませんが、詳細はありません。
Linux と Windows での作業で十分であり、大きなファイルに関心がない場合は、おそらく fseek/ftell メソッドで問題ありません。それ以外の場合は、システム固有の方法を使用してファイルのサイズを決定することを検討する必要があります。
また、ファイルのサイズがわかるものは、その時点でのサイズしか分からないことに注意してください。ファイルのサイズは、アクセスする前に変更される可能性があります。