24

ファイルに書き込んでいるときにどのようseekg()に動作するかについて、いくつかの明確化を探しています。seekp()たとえば、次のようなファイルがあったとします。

offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10

ここで、ファイルを開いて、値の読み取りと書き込みをシークしたいと考えています。

fstream file;
file.open("file.txt", fstream::in |fstream::out | fstream::binary);
file.seekp(0, ios::end) // seek to the end of the file
int eofOffset = file.tellp(); // store the offset of the end-of-file, in this case 20

int key = 0;

file.seekg(12, ios::beg); // set the seek cursor to offset 12 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 8
file.seekg(8, ios::beg); // set the seek cursor to offset 8 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 6

ここで、ファイルの最後に書き込みたいと思います。seekg()関数はシーク カーソルを移動するだけなので、seekp()カーソルはファイルの最後にあるはずですよね? そう:

int newKey = 12;
file.write((char *) &newKey, sizeof(int));

私のファイルは次のようになります:

offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
offset 20: 12

オフセットをシークし、その値を挿入したばかりの値へのオフセットとして書き込むことを選択した場合、ファイルはどうなりますか。たとえば、そのオフセットに 12 を挿入したのでoffset 8保持したいと思います。eofOffset = 20

私が行った場合:

file.seekp(8, ios::beg);
file.write((char *) &eofOffset, sizeof(int));

私のファイルを次のように正しく書き換えますか?

offset 0: 2
offset 4: 4
offset 8: 20
offset 12: 8
offset 16: 10
offset 20: 12

seekg()およびseekp()関数を使用してエラーが発生した場合はお知らせください。

4

1 に答える 1

24

クラス テンプレートstd::basic_filebufは単一のファイル位置を保持します

§ 27.9.1.1

  1. クラス basic_filebuf は、入力シーケンスと出力シーケンスの両方をファイルに関連付けます。
  2. クラス basic_filebuf のオブジェクトによって制御されるシーケンスの読み取りと書き込みに関する制限は、標準 C ライブラリ FILE での読み取りと書き込みの場合と同じです。
  3. 特に:
    • ファイルが読み取り用に開かれていない場合、入力シーケンスを読み取ることはできません。
    • ファイルが書き込み用に開かれていない場合、出力シーケンスを書き込むことはできません。
    • ジョイント ファイルの位置は、入力シーケンスと出力シーケンスの両方で維持されます。

これが意味することは、std::basic_fstreamデフォルトで a を使用する a を使用するstd::basic_filebufと、単一のファイル位置が と の両方によって移動されるseekp()ということseekg()です。別の変数を使用してポジションの 1 つを格納し、後でシークできるようにしない限り、プットポジションと取得ポジションを個別に追跡することはできません。

ポイント 2 の意味は、読み取りと書き込みの間でfstream、出力から入力に変更するときにバッファーをフラッシュするか、ファイル位置をシークする必要があり、出力から入力に変更するときにファイルの最後にいるか、ファイル位置をシークする必要があるということです。インプットからアウトプットへ。

これらの制限の詳細については、C99 標準のセクション 7.19.5.3/7 (「fopen関数」)、または C11 の 7.21.5.3/7 を参照してください。

于 2013-03-28T03:02:06.340 に答える