8

非常に簡単に言えば、次のコード スニペットがあります。

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.

何故ですか?書き込まれたバイト数がファイル ポインタと一致しないのはなぜですか?

4

4 に答える 4

19

ファイルをテキストモードで開いているため、LFなどの行末マーカーがCR/LFに変換されます。

これは、Windowsで実行している場合に発生する可能性があります(ファイル名がで始まる場合は、おそらくそうです"c:\")。

ファイルを"wb"モードで開くと、番号が同じであることがわかると思います。

FILE* test = fopen("C:\\core.u", "wb");

C99標準には次のように書かれてい7.19.5.3 The fopen functionます:

引数モードは文字列を指します。文字列が次のいずれかである場合、ファイルは指定されたモードで開かれます。それ以外の場合、動作は定義されていません。

r読み取り用にテキストファイルを開き、
w長さをゼロに切り捨てるか、
a追加書き込み用のテキストファイルを作成します。ファイルの終わりに書き込むためのテキストファイルを開くか作成します
rb。読み取り用のバイナリファイルを開き、
wb長さをゼロに切り捨てるか、
ab追加を書き込むためのバイナリファイルを作成します。ファイルの終わりに書き込むためのバイナリファイルを開くか作成する
r+更新(読み取りと書き込み)のためにテキストファイルを開く
w+長さゼロに切り捨てるか、更新
a+追加用のテキストファイルを作成します。更新用のテキストファイルを開くか作成するか、ファイルの終わりに書き込む
r+brb+、更新用にバイナリファイルを開く(読み取りと書き込み)
w+bwb+、長さをゼロに切り捨てるか、更新
a+bまたはab+追加用のバイナリファイルを作成します。更新用のバイナリファイルを開くか作成し、ファイルの終わりに書き込みます

とを区別していることがわかりwますwbこの2つを異なる方法で処理するために実装が必要になるとは思いませんが、通常、バイナリデータにバイナリモードを使用する方が安全です。

于 2008-09-28T02:23:13.240 に答える
0

ファイルポインタはクッキーです。価値はありません。これを使用できる唯一のことは、ファイル内の同じ場所をシークすることです。ftell が増加する値を返すことを ISO C が保証しているかどうかさえわかりません。これが信じられない場合は、さまざまな seek() モードを見てください。それらが存在するのは、位置が単純なバイト オフセットではないためです。

于 2008-09-29T12:32:17.930 に答える
0

fwrite は何を返しますか? 通常、戻り値は書き込まれたバイト数になります。また、fseek の直前に ftell() は何と答えますか?

オペレーティング システム、C コンパイラのバージョン、および C ライブラリを知っておくと役立つ場合があります。

于 2008-09-29T04:26:58.083 に答える
0

Windows は実際には、フラッシュやおそらく fsync なしですべてのデータをファイルに書き出すわけではありません。多分それが理由です

于 2010-02-12T23:55:54.363 に答える