很长一段时间没有使用C ++的i / o工具(而是使用C linux API操作),我试图至少熟悉C ++正确做事的方式。我在Ubuntu 12.04下工作,根据C ++ 98,使用gcc -Wall编译没有错误或警告。当我需要创建一个我将首先写入的新文件,然后再读取时,问题出现了。问题如下:
#include <fstream>
std::fstream::openmode o_M = std::fstream::in | std::fstream::out;
std::fstream::openmode o_M1 = o_M | std::fstream::trunc;
std::fstream* preproc;
preproc = new std::fstream(out_Name.c_str(), o_M1); // (1)
if ( !(preproc->good()) )
errExit(1, "can't open file <%s>", out_Name.c_str());
preproc->put('c');
(*preproc) << "foo";
据我所知,这应该将“cfoo”写入文件;但是,没有任何内容写入,而文件是使用适当的权限创建的。我已经经历了许多可能是错误的迭代(清除流;以不同模式打开;明确地首先打开指向文件; ...),但无济于事。此外,在同一个项目的早期,我创建并使用指向现有文件的fstream指针没问题(使用相同的语法,没有openmode限定符(我当然也试过不对文件使用openmodes)上面)) - 仅从现有文件中读取。
当我改为使用非指针访问时,如
std::fstream TEST(out_Name.c_str(), o_M1); // (etc, ancillary changes)
一切正常。
我很困惑。我可能没有看到森林里的树木,如果有人指出我错过了什么,我将不胜感激。
答案 0 :(得分:5)
您不是flush
,close
或delete
流,因此缓冲区不会被刷新。您的堆栈版本有效,因为当对象在超出范围后被销毁时,流被刷新并关闭。
刷新流,例如通过调用flush
或close
,或删除指针delete preproc;
。如果可能的话,最好还是不要使用在堆上分配的对象。
您也可以通过调用
将fstream
设置为无缓冲模式
preproc->rdbuf()->pubsetbuf(NULL, 0); // nullptr for C++11
打开流后立即打开,虽然这不太可能是你想要的。
如果必须使用堆,使用C ++ 11,您可以利用std::unique_ptr
/ std::shared_ptr
。如果你遇到C ++ 98,那么还有std::auto_ptr
(告诫者)。