对于以下代码:
fstream file("file.txt", ios::in):
//some code
//"file" changes here
file.close();
file.clear();
file.open("file.txt", ios::out | ios::trunc);
如何更改最后三行以使当前文件不关闭,而是“重新打开”所有内容都被清除?
如果我正确理解了这个问题,您想清除文件的所有内容而不关闭它(即通过设置 EOF 位置将文件大小设置为 0)。据我所知,您提出的解决方案是最吸引人的。
您的另一个选择是使用特定于操作系统的函数来设置文件的结尾,例如 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
实际上表现得像一个流,这样你就可以编写reopenable_stream<<foo;
而不是reopenable_stream.f<<foo
IMO,这看起来有点过头了。