首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::with与std::ate在结束时未打开

std::with与std::ate在结束时未打开
EN

Stack Overflow用户
提问于 2015-03-12 00:08:46
回答 1查看 3.8K关注 0票数 13

我正在尝试打开一个输出文件并将其附加到其中。附加后,我希望将输出位置移到文件中的其他位置,并覆盖现有数据。据我所知,std::ios_base::app将强制全部写在文件的末尾,这不是我想要做的。因此,我认为std::ios_base::ate是传递给std::ofstream::open()的正确标志。然而,它似乎没有象预期的那样发挥作用:

代码语言:javascript
复制
// g++ test.cpp
// clang++ test.cpp
// with and without -std=c++11
#include <iostream>
#include <fstream>

int main() {
    std::streampos fin, at;
    {
        std::ofstream initial;
        initial.open("test", std::ios_base::out | std::ios_base::binary);
        if ( not initial.good() ) {
            std::cerr << "initial bad open" << std::endl;
            return 1;
        }
        int b = 100;
        initial.write((char*)&b, sizeof(b));
        initial.flush();
        if ( not initial.good() ) {
            std::cerr << "initial write bad" << std::endl;
            return 1;
        }
        fin = initial.tellp();
    }
    {
        std::ofstream check;
        check.open("test", std::ios_base::out | std::ios_base::binary | std::ios_base::ate);
        if ( not check.good() ) {
            std::cerr << "check bad open" << std::endl;
            return 1;
        }
        at = check.tellp();
        if ( fin != at ) {
            std::cerr << "opened at wrong position!\nfin:\t" << fin << "\n" << "at:\t" << at << std::endl;
            return 1;
        }
        int bb = 200;
        check.write((char*)&bb, sizeof(bb));
        check.flush();
        if ( not check.good() ) {
            std::cerr << "check write bad" << std::endl;
            return 1;
        }
        at = check.tellp();
    }
    if ( (fin + std::streampos(sizeof(int))) != at ) {
        std::cerr << "overwrite?\nfin:\t" << fin << "\n" << "at:\t" << at << std::endl;
        return 1;
    }
    return 0;
}

特别是,在上面的示例中,std::ios_base::ate似乎没有将初始输出指针移到末尾。显然,这将导致第一次写入覆盖文件的开头(这就是我的麻烦所在)。

似乎要么实现不正确,要么cplusplus.com不正确(“输出位置从文件末尾开始”)。cppreference.com是模棱两可的(“在打开后立即查找到流的末尾”:哪个流?)。

显然有一个简单的解决方法:只需使用stream.seekp(0, std::ios_base::end)

因此,我的问题是:我的代码不正确吗?实施是否不正确?参考站点是否不正确?任何洞察力都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-12 00:27:04

如N4296 filebuf.members中的下图所示

组合binary | out将以stdio等效的"wb"打开文件,后者将是truncate to zero length or create binary file for writing (N1570 7.21.5.2)。

对于一个ofstream来说,这听起来是违反直觉的,如果您不希望您的文件被截断,则需要添加in标志,如果您希望避免截断并在每次写入时寻求文件的末尾,则需要添加app

额外提示:与fstream不同的是,ifstreamofstream将自动或分别使用向构造函数或open提供的任何标志的std::ios_base::instd::ios_base::out。还可以使用对象本身访问标志:

代码语言:javascript
复制
std::ofstream check("test", check.in | check.binary | check.ate);

good的检查也可以缩短为if (!initial)等。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28999745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档