Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrap C-style files in C++ stream [duplicate]

Tags:

c++

iostream

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?

like image 721
Neil Kirk Avatar asked Oct 09 '13 11:10

Neil Kirk


Video Answer


1 Answers

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 the iostream is still referring to it
  • you need to manually close the FILE*, the stdio_filebuf won't do that when constructed from a FILE*
  • be sure to flush the stream before closing the FILE*, otherwise there could be unwritten data sitting in the stdio_filebuf's buffer that cannot be written out after the FILE* is closed.
like image 61
Jonathan Wakely Avatar answered Sep 29 '22 08:09

Jonathan Wakely