Search code examples
c++fstreamifstreamofstream

What is the difference between ifstream, ofstream and fstream?


In C++ file handling, I came across ifstream, ofstream and fstream. Can anyone tell me the main difference between these?


Solution

  • This is how the class hierarchy looks like: From https://www.cplusplus.com/img/iostream.gif

    The three classes that deal with file handling are:

    • basic_ifstream
    • basic_ofstream
    • basic_fstream

    ifstream, ofstream and fstream are "char" template specializations which means they are nothing but basic_ifstream<char>, basic_ofstream<char> and basic_fstream<char> i.e. they deal with reading and writing chars from a file.

    • ifstream is input file stream which allows you to read the contents of a file.
    • ofstream is output file stream which allows you to write contents to a file.
    • fstream allows both reading from and writing to files by default. However, you can have an fstream behave like an ifstream or ofstream by passing in the ios::open_mode flag.

    ios::openmode Flags


    The open mode flags are:

    Flag Description
    ios::app All write operations must occur at the end of the file
    ios::binary Open in binary mode
    ios::in Open for reading
    ios::out Open for writing
    ios::trunc Empty the contents of the file after opening
    ios::ate Go to the end of the file after opening

    These flags are additive which means you can combine multiple flags using the bitwise OR | operator. If I want to open the file in binary mode and append, I can combine the flags as follows:

    ios::binary | ios::app
    
    • ifstream always has the ios::in flag set and it cannot be removed. Similary, ofstream always has the ios::out flag set and it cannot be removed. Any other flags added will be combined with ios::in for ifstream and ios::out for ofstream
    • On the other hand, if you do not pass any flags to fstream, the default is ios::in | ios::out, so you can read from as well as write to the file. But if you specify a flag explicitly for fstream like ios::in, it will be opened only for reading, like an ifstream.

    How to pass flags?

    You can do so in the constructor or when calling open():

    ifstream infile("filepath", ios::binary); //Open the file for reading in binary mode, ios::in will always be set
    ofstream outfile("filepath", ios::trunc); // Open the file for writing and clear its contents, ios::out is implicitly set
    fstream inoutfile("filepath") // default flag will be: ios::in | ios::out hence both reads and writes possible
    fstream infile("filepath", ios::in) // file will be opened in read mode like fstream
    

    It is basically possible to never use ifstream and ofstream and always use fstream with the required flags. But it is prone to accidental errors while setting the flags. Hence, using ifstream you can be sure that writes will never occur and with ofstream only writes will take place.

    Edit (ios::noreplace)

    C++ 23 adds the ios::noreplace flag which opens a file exclusively for writing. This flag already existed in some implementations but is now standardized in C++ 23. If the file already exists, it fails to open.