指针访问std :: fstream时出现问题

gno*_*ule 2 c++ io c++98

在很长一段时间没有使用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";  
Run Code Online (Sandbox Code Playgroud)

据我所知,这应该写"cfoo"到文件; 但是,在使用适当的权限创建文件时,不会写任何内容.我已经经历了许多可能是错误的迭代(清除流;以不同模式打开;明确地首先打开指向文件; ...),但无济于事.此外,在同一个项目的早期,我创建并使用指向现有文件的fstream指针没有问题(使用相同的语法,没有openmode限定符(我当然也试过不对上面的文件使用openmodes)) - 从现有文件虽然.

当我改为使用非指针访问时,如

std::fstream TEST(out_Name.c_str(), o_M1); // (etc, ancillary changes)
Run Code Online (Sandbox Code Playgroud)

一切正常.

我很迷惑.我可能没有看到森林里的树木,如果有人指出我错过的东西,我将不胜感激.

use*_*267 5

您没有flush输入closedelete输入流,因此缓冲区未被刷新.您的堆栈版本有效,因为当对象在超出范围后被销毁时,流被刷新并关闭.

通过调用冲洗流,例如flushclose,或删除您的指针delete preproc;.如果可能的话,最好还是不要使用在堆上分配的对象.

您也可以fstream通过调用将您设置为无缓冲模式

preproc->rdbuf()->pubsetbuf(NULL, 0); // nullptr for C++11
Run Code Online (Sandbox Code Playgroud)

打开流后立即,虽然这不太可能是你想要的.

如果必须使用堆,使用C++ 11可以利用std::unique_ptr/ std::shared_ptr.如果你坚持使用C++ 98,那么(还有std::auto_ptr一点需要注意).