4

C++を使用してファイルの特定の場所にエントリを書き込もうとしています

だから基本的に私は持っています

ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));

しかし、私が何をしても、常にファイルの最後に書き込みます。

iso::appドキュメントによると、これはに関連していると思います

app (append) Set the stream's position indicator to the end of the stream before each output operation

しかし、私がateを使用するか、何も使用しない場合、ファイルの内容は常に消去されます。

どんな助けでも素晴らしいでしょう:)

4

3 に答える 3

5

はい、それios::appがこの振る舞いを引き起こしているのです。に置き換えますios::in | ios::out

編集:あなたの質問からは明らかではありませんでしたが、あなたのコメントは、ファイルの一部を上書きするのではなく、ファイルの途中にデータを挿入しようとしていることを示唆しています。それが実際に当てはまる場合は、そのために2番目のファイルを使用する必要があります。

于 2011-10-28T11:38:44.800 に答える
3

ファイル追加モード

OS(および該当する場合はネットワークファイルシステム)が追加モードをサポートしている場合、追加モードを設定すると、複数のライターが存在する場合に、書き込まれたデータがファイル内の既存のデータを上書きしないことが保証されます。これは、異なるプロセスからのシークと書き込みの間の競合のため、追加モードなしでは実行できないことです。これは、ログファイルの重要な保証です。

追加モードでは、定義上、ファイルの最後にのみ書き込むことができます。

Iostreamオープンモード

[ofstream.cons]によると、をofstream (s, mode)呼び出しますrdbuf()->open(s, mode|ios_base::out)

[filebuf.members]の表「ファイルオープンモード」によると、の動作はオープンモードの観点からfilebuf::open定義されfopenています。

  • out「w」を意味します
  • appapp|outは「a」を意味します
  • in|out「r+」を意味します
  • in|out|trunc「w+」を意味します

によるとfopen man、モードは次のことを意味します。

  • r+ 読み取りと書き込み用に開きます。
  • w ファイルを長さゼロに切り捨てるか、書き込み用のテキストファイルを作成します。
  • w+ 読み取りと書き込み用に開きます。ファイルが存在しない場合は作成され、存在しない場合は切り捨てられます。
  • 追加用に 開く(ファイルの終わりに書き込む)。ファイルが存在しない場合は作成されます。

最後に、ateを意味しfseek(file,0,SEEK_END)ます。

したがって、既存のデータを破棄せずに任意の位置で書き込み用に開く場合は、またはが必要fopen(s,"r+")ですofstream (s, ios::in|ios::out)

IOW、C / C ++では、ファイルを上書きせずに書き込み用に開くには、ファイルへの読み取りアクセス権も必要です。

POSIXの世界

代わりに、 POSIXオープンフラグに直接アクセスするために、 POSIXopen関数を使用することをお勧めします。、、、、、 ...フラグとは異なり、これらははるかに強力であるだけでなく、独立した直交フラグであり、正常に動作します。O_READO_WRITEO_CREATO_EXCLO_TRUNCfilebuf::open

もちろん、この関数は標準のC++の一部ではありません。通常のプログラミングに関連するすべてのシステム(特別な特性を持つニッチ市場ではない)がサポートしていると思いますopen

于 2011-10-28T13:33:30.813 に答える
1

ios::out代わりに使ってみましたios::appか?

編集:

@curiousguyが参照しているドキュメントを読んだ後、切り捨てを防ぐios::in | ios::outだけでなく、必要になるようです。ios::out

于 2011-10-28T11:39:26.217 に答える