【问题标题】:Writing to ofstream using ios::ate overwrites existing file使用 ios::ate 写入 ofstream 会覆盖现有文件
【发布时间】:2020-11-03 16:20:06
【问题描述】:

我正在尝试将一系列矩阵作为 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标志的文件将在不存在时创建。

标签: c++ ofstream


【解决方案1】:

这是因为ios_base::ate 是一个附加标志,确定打开模式的“主要”标志是inoutapp

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

由于您未指定任何inoutappofstream::open 默认为模式out,相当于"w",它会截断文件。

ios_base::ateios_base::in 结合使用可用于“拖尾”文件。

对于附加到文件,ios_base::app 与您的情况完全匹配。

【讨论】:

  • std::ofstream 不总是默认为std::ios::outstd::ifstreamstd::ios::in
【解决方案2】:

std::ofstream::ate 截断现有文件。您链接的问题的answers 之一也提到了它,您必须将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 << "}";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-21
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 2013-11-04
    • 2014-08-22
    • 2017-09-02
    相关资源
    最近更新 更多