FILE *ポインターの終わりは、書き込まれたデータのサイズと等しくありません
質問
非常に簡単に言えば、次のコードスニペットがあります:
FILE* test = fopen("C:\\core.u", "w");
printf("Filepointer at: %d\n", ftell(test));
fwrite(data, size, 1, test);
printf("Written: %d bytes.\n", size);
fseek(test, 0, SEEK_END);
printf("Filepointer is now at %d.\n", ftell(test));
fclose(test);
そして出力:
Filepointer at: 0
Written: 73105 bytes.
Filepointer is now at 74160.
それはなぜですか?書き込まれたバイト数がファイルポインターと一致しないのはなぜですか?
解決
ファイルをテキストモードで開くため、LFなどの行末マーカーがCR / LFに変換されます。
これは、Windows上で実行している場合に発生する可能性があります(ファイル名が" c:\"
で始まる場合は、おそらくそうです)。
" wb"
モードでファイルを開くと、番号が同じであると思われます:
FILE* test = fopen("C:\\core.u", "wb");
C99標準には、 7.19.5.3 The fopen function
で次のように記述されています:
引数モードは文字列を指します。文字列が次のいずれかである場合、ファイルは 指定されたモードで開きます。それ以外の場合、動作は未定義です。
r
読み取り用のテキストファイルを開く
w
長さ0に切り捨てるか、書き込み用のテキストファイルを作成します
a
追加;ファイルの終わりに書き込むためのテキストファイルを開くか作成します
rb
読み取り用にバイナリファイルを開く
wb
長さ0に切り捨てるか、書き込み用のバイナリファイルを作成
ab
append;ファイルの終わりに書き込むためのバイナリファイルを開くか作成します
r +
更新のためにテキストファイルを開く(読み取りおよび書き込み)
w +
長さ0に切り捨てるか、更新用のテキストファイルを作成します
a +
追加;更新用のテキストファイルを開くか作成し、ファイルの終わりに書き込みます
r + b
またはrb +
バイナリファイルを開いて更新(読み取りおよび書き込み)
w + b
またはwb +
は長さ0に切り捨てるか、更新用のバイナリファイルを作成します
a + b
またはab +
追加;更新用にバイナリファイルを開くか作成し、ファイルの終わりに書き込みます
w
と wb
を区別していることがわかります。この2つを異なる方法で処理するために実装が必要とは思いませんが、通常、バイナリデータにバイナリモードを使用する方が安全です。
他のヒント
fwriteは何を返しますか?通常、戻り値は書き込まれたバイト数である必要があります。 また、ftell()はfseekの直前に何を返しますか?
オペレーティングシステム、Cコンパイラのバージョン、Cライブラリを知ると役立つ場合があります。
ファイルポインタはクッキーです。値はありません。使用できるのは、ファイル内の同じ場所を探すことだけです。 ISO Cがftellが増加する値を返すことを保証しているかどうかさえわかりません。これが信じられない場合は、異なるseek()モードをご覧ください。位置が単純なバイトオフセットではないため、正確に存在します。
windowsは、フラッシュや場合によってはfsyncなしでは、実際にはすべてのデータをファイルに書き込みません。たぶんそれが理由です