Difficulty overloading operator<< for file handling class


March 2019


213 time


I have to:

Define a File_handle class with constructor that takes a string argument (file name), opens the file in the constructor, and closes it in the destructor.

As I understand it, this class is used to provide RAII and I am trying to implement the class using FILE* as basic data structure where my goal basically is to make FILE* a smart pointer:


// Class CFile_handler based on FILE*
class CFile_handler {
    CFile_handler();                                           // default constructor   
    CFile_handler(const std::string& fileName,                 // constructor
                  const std::string& mode);     
    ~CFile_handler ();                                          // destructor

    // modifying member function
    void open_file(const std::string& fileName, 
                   const std::string& mode);

    typedef FILE* ptr;

    CFile_handler(const CFile_handler&);                        // prevent copy creation
    CFile_handler& operator= (const CFile_handler&);            // prevent copy assignment

    ptr c_style_stream;                                         // data member


// Class CFile_handler member implementations
// default constuctor
CFile_handler::CFile_handler() {


// constructor
CFile_handler::CFile_handler(const std::string& fileName, const std::string& mode = "r")
    : c_style_stream( fopen( fileName.c_str(), mode.c_str() ) ) 


// destructor
CFile_handler::~CFile_handler() {
    if (c_style_stream) fclose(c_style_stream);

// Modifying member functions
void CFile_handler::open_file(const std::string& fileName, const std::string& mode) {
    c_style_stream = ( fopen( fileName.c_str(), mode.c_str() ) );

However, I'm having difficulties in overloading I/O operators<< / >>, as I can't figure out how to implement either of them.

How to overload operator<< such that the class works with iostream objects?


As it was proposed by @LokiAstari, it would be better strategy to inherit from istream and define own streambuf.

Could someone give an example or directions for the implementation of streambuf that handles FILE*?

What I want to provide is:

CFile_handler fh("filename.txt", "r");

std::string file_text;
fh >> file_text;


CFile_handler fh("filename.txt", "w");

fh << "write this to file";

2 answers


You can derive types of the std::streams using std::streambuf to handle the FILE*

#include <iostream>
#include <stdio.h>

class OutputFilePointerStream: public std::ostream
    class OutputFilePointerStreamBuf: public std::streambuf
        FILE*   buffer;
            OutputFilePointerStreamBuf(std::string const& fileName)
                buffer  = fopen(fileName.c_str(), "w");
            virtual std::streamsize xsputn(const char* s, std::streamsize n) override
                static char format[30];
                sprintf(format, "%%.%lds", n);
                fprintf(buffer, format, s);
                return n;
    OutputFilePointerStreamBuf       buffer;
        OutputFilePointerStream(std::string const& fileName)
            : std::ostream(nullptr)
            , buffer(fileName)

int main()
    OutputFilePointerStream      fileStream("Test");

    fileStream << "Testing: " << 5 << "><\n";
    fileStream << "Line Again\n";

Your operator<< function is to output a CFile_handler object to a C++ output stream, it's not for outputting to a CFile_handler object.

To output to a CFile_handler object you have two choices:

  1. As a member function

    CFile_handler& CFile_handler::operator<<(int value)
        // Output an integer to the contained file
        return *this;
  2. Or as a non-member function which takes a CFile_handler reference as first argument:

    CFile_handler& operator<<(CFile_handler& file, int value)
        // Output an integer to the file contained in `file`
        return file;

For both of the above variants, you can then do e.g.

CFile_handler my_file(...);
my_file << 1234;