For a project I MUST read/write using a C-style file type. It could be regular FILE, or a C version of gzfile, etc. I'd still like the convenience of using C++ streams. Is there a stream class that redirects to C-style file operations internally? So myfile << hex << myint
eventually becomes fprintf("%a", myint)
or something similar?
Asked
Active
Viewed 2,030 times
6

Neil Kirk
- 21,327
- 9
- 53
- 91
2 Answers
3
There isn't a standard one, but if you MUST do this then you'll have to use something non-standard.
GCC's standard library includes a streambuf type, __gnu_cxx::stdio_filebuf
, which can be constructed with a FILE*
(or a file descriptor), which you can use to replace the streambuf of an fstream
, or just use with a plain iostream
e.g.
#include <stdio.h>
#include <ext/stdio_filebuf.h>
#include <fstream>
int main()
{
FILE* f = fopen("test.out", "a+");
if (!f)
{
perror("fopen");
return 1;
}
__gnu_cxx::stdio_filebuf<char> fbuf(f, std::ios::in|std::ios::out|std::ios::app);
std::iostream fs(&fbuf);
fs << "Test\n";
fs << std::flush;
fclose(f);
}
Things to note about this:
- the
stdio_filebuf
must not go out of scope while theiostream
is still referring to it - you need to manually close the
FILE*
, thestdio_filebuf
won't do that when constructed from aFILE*
- be sure to flush the stream before closing the
FILE*
, otherwise there could be unwritten data sitting in thestdio_filebuf
's buffer that cannot be written out after theFILE*
is closed.

Jonathan Wakely
- 166,810
- 27
- 341
- 521
-
3In your current code sample, fclose() will be called before the stream and buffer's destructors. Even if flushed first, this may be an undefined behavior: You should add a `{}` block that ends before the call to fclose(). – Medinoc Oct 09 '13 at 12:37
-
@Medinoc This is a library extension. Check the source code. I'd hazard a guess Jonathan, being a libstdc++ author, knows how to use its extensions `;-)`. – rubenvb Oct 09 '13 at 12:53
-
1Well it's a long time since I've used those classes so I might have got it wrong. Medinoc's advice is a good idea, although I'm pretty sure it's not going to result in undefined behaviour, you just might lose data and `errno` will get set – Jonathan Wakely Oct 09 '13 at 13:24
2
What you need is an implementation of the streambuf
class that writes on a C file. If there isn't already one in the C++ standard (which would disappoint me a bit, but not surprise me), you can make one and override the right methods.
Note that it will never translate <<
as fprintf(file, ...)
: the result will be more akin to sprintf(buf, ...); fwrite(file, buf)
.

Medinoc
- 6,577
- 20
- 42