将数据附加到 C++ 中的文件,但如果程序重新执行则覆盖

Append data to a file in C++ but overwrite if the program is re-executed

我想使用如下函数将数据附加到文件:

void Fill( string fileName ){
  ofstream outputFile(fileName, ofstream::out | ofstream::app);
  outputFile << data1 << " " << data2 << endl;
  outputFile.close();
}

如果满足某些条件,此函数将在循环中用于写入不同的文件。但我想在程序为 运行 时从空文件开始,即不附加到旧数据。我怎样才能做到这一点? 希望我说清楚了。 谢谢!

您传递给函数的 ofstream::app 参数表示您想要追加到一个文件(如果它已经存在)。默认行为是您正在寻找的。删除那部分,

所以:

ofstream outputFile(fileName, ofstream::out);

使用 ofstream::trunc 打开文件,然后将该文件流传递给您的 Fill 函数(而不是文件名字符串)以附加新数据。

这是一个不完整的例子:

void Fill(ofstream& outputFile) {
  outputFile << data1 << " " << data2 << endl;
}

int main() {
  ofstream outputFile(fileName, ofstream::out | ofstream::trunc);
  Fill(outputFile);
  outputFile.close();
}

(假设您正在将其他数据写入其他地方的文件。如果您只是从 Fill 函数中访问此文件,那么大卫的回答只是从 Fill好多了。

最简单的解决方案是打开您的程序使用的所有文件,而不是 std::ofstream::app 在您在开始时调用一次以截断它们的某些函数中。

void resetFiles()
{
    static char * fileNames[] = {
        // Fill this with filenames of the files you want to truncate
    };

    for( int i = 0; i < sizeof( fileNames ) / sizeof( fileNames[ 0 ] ); ++i )
        std::ofstream( fileNames[ i ] );
}

int main( int argc, char ** argv )
{
    resetFiles();

    ...
}

编辑:由于您确实指定您正在寻找更优雅的解决方案,这就是我想出的。基本上你声明一个新的 class 继承自 std::ofstream 静态 std::map< std::string, bool > 成员称为记录。您添加一个允许您指定文件名的构造函数。然后它通过检查记录中是否存在键 fileName 来查找文件是否已经打开一次。如果不是,它将使用 std::ofstream::trunc 打开它并将 record[ fileName ] 设置为 true。这样,当文件第二次打开时,它知道它必须用 std::ofstream::app.

打开它
class OutFile : public std::ofstream
{
    static std::map< std::string, bool > record;

    // Helper function
    static std::ios_base::openmode hasBeenOpened( std::string fileName )
    {
        // Test if the key is present
        if( record.find( fileName ) == record.end() )
        {
            record[ fileName ] = true;
            return std::ofstream::trunc;
        }
        else
        {
            return std::ofstream::app;
        }
    }

public:
    OutFile( const char * filename )
    : std::ofstream( filename, hasBeenOpened( std::string( filename ) ) ) {}
};

// Don't forget to initialize record
map< std::string, bool > OutFile::record;