Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ file stream open modes ambiguity

For performing file IO in C++ we use the ofstream, ifstream and fstream classes.

  • ofstream: Stream class to write on files
  • ifstream: Stream class to read from files
  • fstream: Stream class to both read and write from/to files

The process of associating a file with a stream object is called "opening the file". When opening a file we can specify the mode in which the file is to be opened. My query is related to the ios::out and ios:in modes.

When I create an ofstream object and open the file with ios::in mode, I am able to write into the file but only if its created already(with ios::out mode file is also created if it doesn't already exist).
But when I create ifstream object and open the file with ios::out mode, I am able to read from the file.

My question is why these modes (ios::in/ios::out) are supplied by the language when the type of the stream(ifstream/ofstream) itself specifies as to which type of operation(input/output) is being performed ?

Also why this ambiguous usage(ofstream with ios::in and ifstream with ios::out) works in one case and fails(though only if file is not already present) in another ?

like image 384
Arun Avatar asked Sep 11 '12 07:09

Arun


People also ask

What is the default open mode if we use ifstream to open the file?

Which of the following is the default mode of the opening using the ifstream class? Explanation: By default, the file is opened in ios::in mode if the file object we are using is of ifstream class.

What are the different types of streams in C file handling?

These include ifstream, ofstream, and fstream. These classes are derived from fstrembase and from the corresponding iostream class. These classes, designed to manage the disk files, are declared in fstream and therefore we must include fstream and therefore we must include this file in any program that uses files.

Which of the following opens the file associated with the stream?

std::fstream::open Opens the file identified by argument filename , associating it with the stream object, so that input/output operations are performed on its content. Argument mode specifies the opening mode. If the stream is already associated with a file (i.e., it is already open), calling this function fails.

What is a FileStream in C?

C# FileStream FileStream provides a Stream for a file, supporting both synchronous and asynchronous read and write operations. A stream is a flow of data from a source into a destination. The source or destination can be a disk, memory, socket, or other programs.


1 Answers

The ofstream, ifstream and fstream classes are high level interfaces for the underling filebuf, which one can get through the rdbuf() member function of the stream.

According to the standard when you open an ofstream with some mode mode, it opens the underlining stream buffer as with mode | ios_base::out. Analogously ifstream uses mode | ios_base::in. fstream passes the mode parameter verbatim to the underlining stream buffer.

What the above implies is that the following code opens the file with exactly the same open flags:

fstream f("a.txt", ios_base::in | ios_base::out);
ifstream g("a.txt", ios_base::out);
ofstream h("a.txt", ios_base::in);

After these lines you can do exactly the same things with f.rdbuf(), g.rdbuf() and h.rdbuf(), and all the three act as if you opened the file with the C call fopen("a.txt", "r+"), which gives you read/write access, does not truncate the file, and fails if the file does not exist.

So, why do we have three different classes? As I've already said, these are high level classes providing a high-level interface over the lower-level stream buffer. The idea is that ifstream has member functions for input (like read()), ofstream has member functions for output (like write()) while fstream has both. For example you cannot do this:

g.write("abc", 3); // error: g does not have a write function

But this works, because, although g is an ifstream, we had opened it with ios_base::out:

g.rdbuf()->sputn("abc", 3); // we still have write access
like image 178
Yakov Galka Avatar answered Nov 13 '22 16:11

Yakov Galka