次のコードの場合:
fstream file("file.txt", ios::in):
//some code
//"file" changes here
file.close();
file.clear();
file.open("file.txt", ios::out | ios::trunc);
現在のファイルを閉じずに、すべてを空白にして「再度開く」ように、最後の3行をどのように変更できますか?
質問を正しく理解している場合は、ファイルを閉じずにすべての内容をクリアします(つまり、EOF位置を設定してファイルサイズを0に設定します)。私が見つけることができるものから、あなたが提示した解決策は最も魅力的です。
他のオプションは、OS固有の関数を使用してファイルの終わりを設定することです。たとえば、Windowsの場合はSetEndOfFile()、POSIXの場合はtruncate()です。
ファイルの先頭から書き始めるだけの場合は、Simonのソリューションが機能します。ファイルの終わりを設定せずにこれを使用すると、最後に書き込んだ位置を超えてガベージデータが存在する状況になる可能性があります。
ファイルを巻き戻すことができます。putポインタをファイルの先頭に戻すと、次に何かを書き込むときに、ファイルの内容が上書きされます。このためにあなたはこのseekp
ように使うことができます:
fstream file("file.txt", ios::in | ios::out); // Note that you now need
// to open the file for writing
//some code
//"something" changes here
file.seekp(0); // file is now rewinded
コンテンツは消去されないことに注意してください。上書きする場合のみ注意してください。
「file.txt」パラメータの受け渡しを避けようとしていて、次のようなものを実装しようとしていると思います。
void rewrite( std::ofstream & f )
{
f.close();
f.clear();
f.open(...); // Reopen the file, but we dont know its filename!
}
ただしofstream
、基になるストリームのファイル名は提供されておらず、既存のデータをクリアする方法も提供されていないため、運が悪いです。(これはseekp
、書き込みカーソルをファイルの先頭に戻すことができるを提供しますが、既存のコンテンツを切り捨てることはありません...)
ファイル名を必要とする関数に渡すだけです
void rewrite( std::ostream & f, const std::string & filename )
{
f.close();
f.clear();
f.open( filename.c_str(), ios::out );
}
または、ファイルストリームとファイル名をクラスにパッケージ化します。
class ReopenableStream
{
public:
std::string filename;
std::ofstream f;
void reopen()
{
f.close();
f.clear();
f.open( filename.c_str(), ios::out );
}
...
};
熱心に感じている場合は、ReopenableStream
実際にストリームのように振る舞わせることができます。そうすれば、IMOreopenable_stream<<foo;
ではなく書くことができますが、それはやり過ぎのようです。reopenable_stream.f<<foo