File Handling in C++

Learn via video course
FREE
View all courses
C++ Course: Learn the Essentials
C++ Course: Learn the Essentials
by Prateek Narang
1000
5
Start Learning
C++ Course: Learn the Essentials
C++ Course: Learn the Essentials
by Prateek Narang
1000
5
Start Learning

Files are primarily used to store data permanently, unlike memory storage which is volatile. C++ provides a comprehensive set of classes and methods in its standard library, mainly the <fstream> header, to manage and manipulate files. This enables operations on text files (text mode) and binary files (binary mode).

The primary classes for file handling in C++ are:

  • ofstream: Represents the output file stream and is used to create and write to files.
  • ifstream: Represents the input file stream and is used to read from files.
  • fstream: Represents the file stream and can be used for both reading from and writing to files.

Steps of File Handling:

  1. Open a File: Before performing any operation on a file, it must be opened. In C++, we use the open() method.

  2. Perform Operation: Once opened, you can perform various operations like reading from or writing to the file.

    • Writing: outfile << "Writing to file." << endl;
    • Reading: infile >> variable;
  3. Close the File: After completing operations on the file, it's essential to close it using the close() method. Closing the file releases the resources that were allocated for that file during the operation.

C++ Streams for File Handling

In C++, file handling operations are achieved through streams. A stream is an abstract entity where a program can either insert or extract data. It acts as an intermediary between the program and the input/output devices. When dealing with files, C++ uses specific stream classes, which manage and manipulate files.

Classes for File Stream in C++:

  1. ifstream: Short for input file stream. This class is designed to read information from files.

    Example:

  2. ofstream: Short for output file stream. This class is used for creating files and writing information to them.

    Example:

  3. fstream: Represents the generic file stream class. It can be used for both reading from and writing to files. It is more versatile as compared to ifstream and ofstream, but knowing when to use the specialized classes is crucial for effective programming.

    Example:

Opening a File

To start working with the file, first, we need to open it in our program. We can either open our file with the constructor provided by the file I/O classes or call the open method on the stream object. Before begin discussing how the file can be opened, it is necessary to take a moment to discuss several opening modes.

Opening Modes

There are several modes we can specify when opening a file. These modes correspond to various controls given to stream objects during file handling in c++. The opening mode's description and syntax are given below in tabular form.

ModeSyntaxDescription
Readios::inOpens file for reading purpose.
Writeios::outOpens a file for writing purposes.
Binaryios::binaryAll operations will be performed in binary mode.
Truncate before Openios::truncIf the file already exists, all content will be removed immediately.
Appendios::appAll provided data will be appended in the associated file.
At Endios::ateIt opens the file and moves the read/write control at the End of the File. The basic difference between the ios::app and this one is that the former will always start writing from the end, but we can seek any particular position with this one.

1. Open a File Using Constructor

Each class has two types of constructors: default and those that specify the opening mode and the associated file for that stream.

2. Open a File Using stream.open() Method

The open() is a public member function of all these classes. Its syntax is shown below.

The open() method takes two arguments one is the file name, and the other is the mode in which the file is going to open.

The is_open() method is used to check whether the stream is associated with a file or not. It returns true if the stream is associated with some file; otherwise returns false.

Reading from a File

We read the data of a file stored on the disk through a stream. The following steps must be followed before reading a file,

  • Create a file stream object capable of reading a file, such as an object of ifstream or fstream class.
  • Open a file through constructor while creating a stream object or by calling the open method with a stream object.
  • Check whether the file has been successfully opened using is_open(). If yes, then start reading.

1. Using get() Method

Output:

Explanation:

  • First of all, we have created a stream object of the ifstream class and are providing the file name to open it in reading mode(default).
  • Next, we check whether the file is being opened successfully or not. If yes, we read one character at a time until the file is good.
  • The good() function returns true if the end of the file is not reached and there is no failure.

2. Using getline() Method

Output:

Explanation:

  • At the beginning of the program, we opened the file with the constructor of the ifstream class.
  • If the file is successfully opened, the 'open' function will return true, and the if block will be executed.
  • In the while loop, we are checking whether the file stream is good for operations or not. When the end of the file is reached, the good function will return false.
  • We have declared a string to store each line of file through the getline function, and later we are printing that string.

Writing to a File

In writing, we access a file on disk through the output stream and then provide some sequence of characters to be written in the file. The steps listed below need to be followed in writing a file,

  • Create a file stream object capable of writing a file, such as an object of ofstream or fstream class.
  • Open a file through constructor while creating a stream object or by calling the open method with a stream object.
  • Check whether the file has been successfully opened. If yes, then start writing.

1. Writing in Normal Write Mode

Output:

Explanation:

  • << operator is used for writing on the file.
  • The text given above will be shown in our sample.txt after running the program.

2. Writing in Append Mode

Output:

Explanation:

  • The same sample.txt, which was used in the last example, has more content appended to it now.

3. Writing in Truncate Mode

Output:

Explanation:

  • Again, we are using the same sample.txt file from the previous Example. Now all older content is being removed.

Closing a File

The concept of closing a file during file handling in c++ refers to the process of detaching a stream with the associated file on disk. The file must be closed after performing the required operations on it. Here are some reasons why it is necessary to close the file,

  • The data might be in the buffer after the write operation, so closing a file will cause the data to be written in the file immediately.
  • When you need to use the same stream with another file, it is a good practice to close the previous file.
  • To free the resources held by the file.

When the object passes out of scope or is deleted, the stream destructor closes the file implicitly.

File Position Pointers

A file position pointer points to a particular index in a file where read or write operations occur. There are two types of pointers get and put. We can find the position of these pointers by associated functions tellg() and tellp(). Also, we can seek(change) the position of the pointer with the function seekg() and seekp(). There, we can either read or write after seeking a particular position. Methods like seekg(), seekp() takes parameters as long integers and seek directions.
A few examples are :
ios::beg (for positioning at the beginning of a stream)
ios::cur (for positioning relative to the current position of a stream)
ios::end (to position relative to the end of a stream)

tellp() & tellg()

tellp() returns the current position of put pointer, which is used with output streams while writing the data to the file.

tellg() returns the current position of get pointer which is used with input streams while receiving the data from the file.

Example:

Output:

Explanation:

  • Before writing anything to the file, it was opened in the out mode; hence the put pointer was at 00.
  • After writing the string Hello Everyone, the put pointer will reach to end of the file, which is 1414.
  • For reading, the get pointer is used, and the initial position of get pointer is 00.
  • After reading five characters from the file, the get pointer reaches 55.

seekg() & seekp()

  • istream& seekg (streampos pos), this function returns the istream object by changing the position of get pointer to pos.
  • istream& seekp (streampos pos), this function returns the ostream object by changing the position of put pointer.
  • We could also overload the seekg() & seekp() by providing an offset. Pointers will move with respect to offsets, i.e., ios_base::beg to start from the beginning of the file, ios_base::end to start from the ending of the file, ios_base::curr to start from the current positions of the pointer.
  • The default value of offset is the beginning of the file.

Example:

Output:

Explanation:

  • Initially, we have written a string into a file named myfile.txt.
  • Later, we have to change the position of the put pointer to the 5th index using seekp() and then write "*" to the file, which will overwrite to file.
  • Then, for the reading operation, we change the get pointer position to the 3rd index, which means reading will now start from that position.
  • As we can see from the output, the string started from the 3rd index, and the 5th index is changed to '*'.

Checking State Flags

The state flags of the file tell about the current state of the file, and there are several functions to retrieve the current state.

  • eof(), This function returns true if the end of the file is reached while reading the file.
  • fail() returns true when the read/write operation fails or a format error occurs.
  • bad() returns true if reading from or writing to a file fails.
  • good() checks the state of the current stream and returns true if the stream is good for working and hasn't raised any error. good() returns false if any of the above state flags return true; otherwise, it returns true.

Flushing a Stream

In C++, the streams get buffered by default for performance reasons, so we might not get the expected change in the file immediately during a write operation. To force all buffered writes to be pushed into the file, we can either use the flush() function or std::flush manipulator.

Conclusion

  • The file I/O in programming means interacting with the file on the disk to receive and provide the data.
  • File Handling is the manipulation of files storing relevant data using a programming language( i.e., C++ in our case).
  • We have three different classes: ifstream, ofstream, and fstream. These all are declared in the fstreamheader and provide us stream through which we can access the file and subsequently performfile handling in C++.
  • To start working with a file, first, we have to open that file. We can do this either during the construction of the stream object or by calling the open() method on the stream object.
  • There could be several modes of file opening we can choose according to our requirements.
  • After working on the file, it is a good practice to close it with the help of the close() method of stream object.