In C++ file handling, I came across ifstream
, ofstream
and fstream
. Can anyone tell me the main difference between these?
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 char
s 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
FlagsThe 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
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
.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.
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.