使用ios::ate模式写入ofstream会覆盖现有文件

4
我要将一系列矩阵作为CSV附加到磁盘上,并发现使用ios::ate会覆盖之前创建的任何现有文件。为了通过一个简化的模型说明这个问题,下面的write_nums()函数的第二次调用会导致丢失在第一次调用中写入的任何数据。是否有方法可以修复这个问题?
先前在ofstream open modes: ate vs app中给出的解决此问题的方法似乎不太理想,因为它只适用于输出所定向的文件已经存在的情况。
void write_nums()
{
    std::ofstream out_file;

    out_file.open("test.txt", std::ofstream::ate);
    if (!out_file.good())
    {
        std::cerr << "Error while opening output file!" << '\n';
    }
    out_file.seekp(0, std::ios::end);
    out_file << "{";
    for (int i = 0; i < 10; ++i)
    {
        out_file << i << ',';
    }
    out_file.seekp(-1, std::ios::end);
    out_file << "}";
}

只有在输出所指向的文件已经存在的情况下,它才能正常工作。但是,如果使用 app 标志,则会在文件不存在时创建该文件。 - anastaciu
2个回答

2
那是因为ios_base :: ate 是一个额外的标志,决定打开模式的“主要”标志是inoutapp

有效的打开模式标志组合列在[input.output]/2中。

由于您没有指定inoutapp中的任何一个,ofstream :: open 默认为out 模式,这相当于"w",它会截断文件。

ios_base :: ate ios_base :: in 结合使用可用于“尾随”文件。

对于追加到文件,有ios_base :: app 正好符合您的情况。


std::ofstream 总是默认为 std::ios::out,而 std::ifstream 默认为 std::ios::in,对吗? - Amal K

2

std::ofstream::ate截断现有文件。你链接的问题的答案之一也提到了它,你必须将atein结合使用以避免截断。使用app不能让你操作查找。


void write_nums()
{
    std::ofstream out_file("test.txt", std::ofstream::ate | std::ofstream::in);
    if (!out_file.good())
    {
        std::cerr << "Error while opening output file!" << '\n';
    }
    out_file.seekp(0, std::ios::end);
    out_file << "{";
    for (int i = 0; i < 10; ++i)
    {
        out_file << i << ',';
    }
    out_file.seekp(-1, std::ios::end);
    out_file << "}";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接