File Handling in C++

In this tutorial chapter we will understand the file handling mechanism in C++. We will understand:

  • What are files and streams
  • Opening a file
  • File Opening Modes
  • Writing to a file
  • Reading from a file
  • Closing a file
  • Error Handling Functions
  • Binary Files
  • File Pointers & their Manipulation
What are files and streams?

Files are used to store data permanently. A stream is an abstraction that represents a device on which input and output operations are performed. A stream can basically be represented as a source or destination of characters of indefinite length.

C++ file handling provides a mechanism to store output of a program in a file and read from a file on the disk. So far, we have been using <iostream> header file which provide functions cin and cout to take input from console and write output to a console respectively. Now, we introduce one more header file <fstream> which provides data types or classes ( ifstream , ofstream , fstream ) to read from a file and write to a file.

file handling in C++ programming 

Data TypeDescription
ofstreamThis data type represents the output file stream and is used to create files and to write information to files.
ifstreamThis data type represents the input file stream and is used to read information from files.
fstreamThis data type represents the file stream generally, and has the capabilities of both ofstream and ifstream which means it can create files, write information to files, and read information from files.
Opening a File

A file must be opened before you can read from it or write to it. Either the ofstream or fstream object may be used to open a file for writing and ifstream object is used to open a file for reading purpose only.
Following is the standard syntax for open() function, which is a member of fstream, ifstream, and ofstream objects.

void open(const char *filename, ios::openmode mode);

Here, the first argument specifies the name and location of the file to be opened and the second argument of the open() member function defines the mode in which the file should be opened.

File Opening Modes
Mode FlagDescription
ios::appAppend mode. All output to that file to be appended to the end.
ios::ateOpen a file for output and move the read/write control to the end of the file.
ios::inOpen a file for reading.
ios::outOpen a file for writing.
ios::truncIf the file already exists, its contents will be truncated before opening the file.
Write to a File

In order to write to a file we use the insertion operator (<<). The only difference is that you use an ofstream or fstream object instead of the cout object.

Read from a File

In order to read from a file in C++, we use the extraction operator (>>). The only difference is that you use an ifstream or fstream object instead of the cin object.

Closing a File

When C++ program terminates, it automatically closes any opened files and streams but it is always a good practice to close opened files explicitly. Following is the syntax of closing a file in C++ which can be used with objects of fstream, ifstream, and ofstream objects.

void close();
File Handling in C++ Example Program
#include <fstream>
#include <iostream>
using namespace std;
 
int main () {
    
   char data[100];

   // open a file in write mode.
   ofstream outfile;
   outfile.open("afile.dat");

   cout << "Writing to the file" << endl;
   cout << "Enter your name: "; 
   cin.getline(data, 100);

   // write inputted data into the file.
   outfile << data << endl;

   // close the opened file.
   outfile.close();

   // open a file in read mode.
   ifstream infile; 
   infile.open("afile.dat"); 
 
   cout << "Reading from the file" << endl; 
   infile >> data; 

   // write the data at the screen.
   cout << data << endl;
   
   // close the opened file.
   infile.close();

   return 0;
}
Output
Writing to the file
Enter your name: SimpleSnippets
Reading from the file
SimpleSnippets
Error Handling Functions
FunctionReturn value and Meaning
eof()Returns true (non zero) if end of file is encountered while reading; otherwise return false(zero)
fail()Return true when an input or output operation has failed
bad()Returns true if an invalid operation is attempted or any unrecoverable error has occurred.
good()Returns true if no error has occurred.
Binary Files

By default, C++ opens the files in text mode. For binary files, reading and writing data with the extraction and insertion operators (<< and >>) and functions like getline is not efficient, since we do not need to format any data and data is likely not formatted in lines.

File streams include two member functions specifically designed to read and write binary data sequentially: write and read. The first one (write) is a member function of ostream (inherited by ofstream). And read is a member function of istream (inherited by ifstream). Objects of class fstream have both. Their prototypes are:

write ( memory_block, size );
read ( memory_block, size );

Where memory_block is of type char* (pointer to char), and represents the address of an array of bytes where the read data elements are stored or from where the data elements to be written are taken. The size parameter is an integer value that specifies the number of characters to be read or written from/to the memory block.

Writing to a Binary File
struct Person
{
  char name[50];
  int age;
  char phone[24];
};

int main()
{
  Person me = {"Robert", 28, "364-2534"};
  Person book[30];
  int x = 123;
  double fx = 34.54;
  ofstream outfile;
  outfile.open("junk.dat", ios::binary | ios::out);
  outfile.write(&x, sizeof(int)); // sizeof can take a type
  outfile.write(&fx, sizeof(fx)); // or it can take a variable name
  outfile.write(&me, sizeof(me));
  outfile.write(book, 30*sizeof(Person))
  outfile.close();
}
Reading from a Binary File
int main() 
  { 
    int x; 
    ifstream infile; 
    infile.open("silly.dat", ios::binary | ios::in) 
    infile.read(&x, 7); // reads 7 bytes into a cell that is either 2 or 4 
  }
File Pointer & their Manipulation

The read operation from a file involves get pointer. It points to a specific location in the file and reading starts from that location. Then, the get pointer keeps moving forward which lets us read the entire file. Similarly, we can start writing to a location where put pointer is currently pointing. The get and put are known as file position pointers and these pointers can be manipulated or repositioned to allow random access of the file. The functions which manipulate file pointers are as follows :

FunctionDescription
seekg( )Moves the get pointer to a specific location in the file
seekp( )Moves the put pointer to a specific location in the file
tellg( )Returns the position of get pointer
tellp( )Returns the position of put pointer

The function seekg( n, ref_pos ) takes two arguments :
n denotes the number of bytes to move and ref_pos denotes the reference position relative to which the pointer moves. ref_pos can take one of the three constants : ios :: beg moves the get pointer n bytes from the beginning of the file, ios :: end moves the get pointer n bytes from the end of the file and ios :: cur moves the get pointer n bytes from the current position. If we don’t specify the second argument, then ios :: beg is the default reference position.
The behaviour of seekp( n, ref_pos ) is same as that of seekg( ).

Random Access of File Using File Pointer Manipulation
#include<iostream>
#include<fstream>
using namespace std;

int main() {
   fstream fp;
   char buf[100];
   int pos;

   // open a file in write mode with 'ate' flag
   fp.open("random.txt", ios :: out | ios :: ate);
   cout << "\nWriting to a file ... " << endl;
   fp << "This is a line" << endl; // write a line to a file
   fp << "This is a another line" << endl; // write another file
   pos = fp.tellp();
   cout << "Current position of put pointer : " << pos << endl;
   // move the pointer 10 bytes backward from current position 
   fp.seekp(-10, ios :: cur);
   fp << endl << "Writing at a random location  ";
   // move the pointer 7 bytes forward from beginning of the file
   fp.seekp(7, ios :: beg);
   fp << " Hello World  ";
   fp.close(); // file write complete
   cout << "Writing Complete ... " << endl;

   // open a file in read mode with 'ate' flag
   fp.open("random.txt", ios :: in | ios :: ate);
   cout << "\nReading from the file ... " << endl;
   fp.seekg(0); // move the get pointer to the beginning of the file
   // read all contents till the end of file
   while (!fp.eof()) {
      fp.getline(buf, 100);
      cout << buf << endl;
   }
   pos = fp.tellg();
   cout << "\nCurrent Position of get pointer : " << pos << endl;
   return 0;
}
Output
Writing to a file …
Current Position of put pointer : 40
Writing Complete …

Reading from the file …
This is Hello World is a anot
Writing at random location

Current Position of get pointer : -1

Watch it on YouTube

Leave a Reply

Your email address will not be published. Required fields are marked *