2

「fstream」を使用してバイナリ ファイルからバイトを読み取り、そのバイトを変更して書き戻すことができるかどうかを知りたかったのです。このコードを試してみましたが、うまくいきませんでした。何も起こりませんでしたが、正しく読み取れたことは確かです。

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
file.seekg(0, ios::end);
int size=file.tellg();
file.seekg(0,ios::beg);
char buffer;    
for(int i=0;i<size;i++)
{
    file.read((char*)&buffer,sizeof(char));
    buffer=(buffer+7)%256;
    file.write((char*)&buffer, sizeof(char));
}

次のように読んだ後、ファイルポインターを1バイト戻す必要があります。

file.seekg(-1, ios::cur);

前もって感謝します。

4

4 に答える 4

6

はい。質問で示唆したように、以前に読み取ったバイトを上書きする場合は、seekg を使用してファイル ポインターの位置を調整する必要があります。各読み取りの後、ファイル ポインターは読み取りバイトの後に配置されます。

于 2010-02-23T09:42:31.347 に答える
2

以前の読み取りバイトの量だけポインターを戻す必要があります。そのため、char -1 を使用します。

file.seekg(-1, std::ios::cur);

データを変更するときは、同じバイト サイズにする必要があることを考慮してください。そうしないと、ファイル内の他のデータが上書きされます。

于 2010-02-23T09:45:05.087 に答える
1

読み取りと書き込みは、同じ位置ポインターを使用します。したがって、連続した値を読み取れるようにしたい場合、値を書き換えるには、読み取った位置にポインターを巻き戻す必要がありますよね?

とはいえ、あなたの場合、データのブロックを読み取り、メモリに変換してから書き戻す方がおそらく効率的です。

于 2010-02-23T09:44:21.773 に答える
0

まず、実際に開いたファイルを常に確認する必要があります。

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
if ( ! file.is_open() ) {
    throw "open failed";
}

次に、動作することが期待される読み取りと書き込みが機能したことを常に確認する必要があります。

if ( ! file.read((char*)&buffer,sizeof(char)) ) {
   throw "read failed";
}

そして最後に、使用しているオープンフラグの組み合わせが特定のプラットフォームで有効であることを確認する必要があります-MacOSXでstd::fstreamを読み取って追加できないのはなぜですか?を参照してください。これについての議論のために-私はあなたのコードのios::ateフラグを削除することを提案します。

于 2010-02-23T10:16:41.440 に答える