【发布时间】:2015-05-14 00:25:07
【问题描述】:
我正在尝试打开一个文件进行输出并附加到它。附加到它之后,我想将我的输出位置移动到文件中的其他位置并覆盖现有数据。据我了解,std::ios_base::app 将强制所有写入位于文件末尾,这 不是我想要做的。因此,我相信std::ios_base::ate 是传递给std::ofstream::open() 的正确标志。但是,它似乎没有按预期工作:
// 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.cppreference.com/w/cpp/io/basic_filebuf/open。使用
out而不使用app或in会截断。