(Newsgroups: comp.lang.c++, 4 Oct 99)
EMIL: emil@koblo.com wrote:
> How can I construct a std::ofstream from a FILE* or otherwise attach
> the FILE* to the ofstream?
KUEHL: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
The short answer is: You can't. The longer answer is: You can but you
don't want to, although you think you want to. Since you have abstracted
the problem into something which you don't want, it is hard to tell what
you really want to do... The exhaustive answer depends somewhat on what
you really want to do.
Since you are aware of 'std::ofstream', you probably don't want to
access file for which you have the name give. Instead, you apparently
got an opened stream, identified by a 'FILE*' (or whatever) and you want
to use this stream using iostreams. Since there is no way to attach one
of the streams defined in the standard C++ library to a 'FILE*' (or a
file descriptor as suggested in another answer), you have to create a
simple stream buffer, eg. something like this (only for output):
#include <streambuf>
#include <cstdio>
class stdiobuf: public std::streambuf {
public:
typedef char char_type;
typedef std::char_traits<char>::int_type int_type;
typedef std::char_traits<char> traits_type;
stdiobuf(std::FILE* file): m_file(file) {}
protected:
int_type overflow(int_type c) {
if (!traits_type::eq_int_type(c, traits_type::eof()))
return std::fputc(c, m_file);
else
return std::fflush(m_file);
}
private:
std::FILE* m_file;
};
You can then use this stream buffer to initialize an 'ostream' (if you
need output, too, you would override additional member functions):
int main() {
stdiobuf buf(std::stdout);
std::ostream out(&buf);
out << "hello, world\n";
}
Of course, if you have something else than a 'FILE*' you might use this,
too, to create a stream buffer. This might be more efficient but might
also be more involved. Also, the above stream buffer is just a starting
point which should do some real work (namely write characters to a file)
but for production code, you would override more virtual functions of
the class 'streambuf' (or, if you need this stuff to be templatized, you
would override functions for the template class 'basic_streambuf').