我有一个非常简单的程序
#include <iostream>
#include <fstream>
void CHECK(std::iostream& s)
{
std::cout << "good(): " << s.good()
<< " fail(): " << s.fail()
<< " bad(): " << s.bad()
<< " eof(): " << s.eof() << std::endl;
}
int main(int argc, const char * argv[])
{
std::fstream ofs("test.txt", std::ios::out | std::ios::trunc);
std::cout << "opened" << std::endl;
CHECK(ofs);
ofs << "Hello, World!\n";
CHECK(ofs);
ofs.close();
std::cout << "closed" << std::endl;
CHECK(ofs);
ofs << "Hello, World!\n";
std::cout << "after operation" << std::endl;
CHECK(ofs);
return 0;
}
使用libc++
,我得到以下最后一行:
good(): 1 fail(): 0 bad(): 0 eof(): 0
预期(或与libstdc++
一起使用):
good(): 0 fail(): 1 bad(): 1 eof(): 0
我已经在OSX的Xcode 9.4.1(或Linux)上进行了测试,但始终保持不变。有人可以向我解释一下这种情况吗?此外,文件内容未更新,因为已关闭。在关闭并进一步操作后,为什么流仍然好?
答案 0 :(得分:1)
我怀疑正在发生的事情是操作正在将数据填充到与流关联的rdbuf
中。只要缓冲区中有空间,该操作就会成功。最终,缓冲区已满,流试图写入文件(已关闭),但失败。
您可以通过循环最后一点来进行测试:
ofs.close();
std::cout << "closed" << std::endl;
CHECK(ofs);
for (int i = 0; i < 500; ++i)
{
ofs << "Hello, World!\n";
std::cout << i << " ";
CHECK(ofs);
}
std::cout << "after operation" << std::endl;
在我的机器上,它在大约300次后失败-并在此之后永远失败。 这是正确的行为吗? (甚至符合标准?) 我不知道。
[稍后:如果我更改libc ++,则在关闭时将缓冲区大小设置为0,则第一次写入失败-因此表明我的分析是正确的。但是,我仍然没有在标准中找到任何关于“应该”做什么的东西。 ]