The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as
well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct. Donald E. Knuth

File Handling

Files are a means to store data in a storage device. 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 Opening Modes
A file can be opened in different modes to perform read and write operations. Function to open a file i.e open( ) takes two arguments : char *filename and ios :: mode. C++ supports the following file open modes :

ModeExplanation
ios :: inOpen a file for reading
ios :: outOpen a file for writing
ios :: appAppends data to the end of the file
ios :: ateFile pointer moves to the end of the file but allows to writes data
in any location in the file
ios :: binaryBinary File
ios :: truncDeletes the contents of the file before opening

If a file is opened in ios :: out mode, then by default it is opened in ios :: trunc mode also i.e the contents of the opened file is overwritten. If we open a file using ifstream class, then by default it is opened in ios :: in mode and if we open a file using ofstream class, then by default it is opened in ios :: out mode. The fstream class doesn't provide any default mode.

File Operations using ifstream and ofstream
Open a file for writing :

#include<iostream>
#include<fstream>
using namespace std;

int main() {
   ofstream ofile; // declaring an object of class ofstream
   ofile.open("file.txt"); // open "file.txt" for writing data
   /* write to a file */
   ofile << "This is a line in a file" << endl;
   ofile << "This is another line" << endl;
   /* write to a console */
   cout << "Data written to file" << endl;
   ofile.close(); // close the file
   return 0;
}
Run this program in your system to write to a file  

Open a file for reading :

#include<iostream>
#include<fstream>
using namespace std;

int main() {
   char data[100]; // buffer to store a line read from file
   ifstream ifile; // declaring an object of class ifstream
   ifile.open("file.txt"); // open "file.txt" for reading
   cout << "Reading data from a file :-" << endl << endl;
   while (!ifile.eof()) { // while the end of file [ eof() ] is not reached 
      ifile.getline(data, 100); // read a line from file
      cout << data << endl; // print the file to console
   }
   ifile.close(); // close the file
   return 0;
}
Run this program in your system to read from a file  

In the first program, a file " file.txt " is created and some data is written into it. The file is created in the same directory in which the program file is saved.
In the second program, we read the file line by line using and then print each line on the console. The while loop continues till the end of file is reached. We ensure that using the condition while( ! ifile.eof( ) ). Note that we can simply use while( ifile ) also.
We can open a file using the constructors of ifstream and ofstream classes instead of using open( ) member function. For e.g, ifstream ifile( "file.text" );. It is a good practice to check if file is opened successfully before proceeding with further operations.

File Operations using fstream
Open a file and append data to the end of the file :

#include<iostream>
#include<fstream>
using namespace std;

int main() {
   char line[100];
   fstream file; // declare an object of fstream class
   file.open("file.txt", ios :: out | ios :: app); // open file in append mode
   if (file.fail()) { // check if file is opened successfully
      // file opening failed
      cout << "Error Opening file ... " << endl;
   }
   else {
      // proceed with further operations
      cout << "Enter a line : ";
      cin.getline(line, 100);
      file << line << endl; // Append the line to the file
      cout << "Line written into the file" << endl;
   }
   return 0;
}
Run this program in your system to write  

Open the file for reading :

#include<iostream>
#include<fstream>
using namespace std;

int main() {
   char line[100];
   fstream file; // declare an object of fstream class
   file.open("file.txt", ios :: out | ios :: app); // open file in append mode
   if (file.fail()) { // check if file is opened successfully
      // file opening failed
      cout << "Error Opening file ... " << endl;
   }
   else {
      // proceed with further operations
      cout << "Enter a line : ";
      cin.getline(line, 100);
      file << line << endl; // Append the line to the file
      cout << "Line written into the file" << endl;
   }
   return 0;
}
Run this program in your system to read from a file  

In the first program, we take a line as input from user and appends that line to the " file.txt ".
In the second program, we read the file character by character using get( ) function. Similarly, we can write a single character to a file using put function.

Writing class objects to a file
There are member functions read( ) and write( ) in the fstream class which allows reading and writing of class objects. These functions can also be used to write array elements into the file. See the program below :

#include<iostream>
#include<fstream>
using namespace std;

// define a class to store student data
class student {
   int roll;
   char name[30];
   float marks;
public:
   student() { }
   void getData(); // get student data from user
   void displayData(); // display data
};

void student :: getData() {
   cout << "\nEnter Roll No. : ";
   cin >> roll;
   cin.ignore(); // ignore the newline char inserted when you press enter
   cout << "Enter Name : ";
   cin.getline(name, 30);
   cout << "Enter Marks : ";
   cin >> marks;
}

void student :: displayData() {
   cout << "\nRoll No. : " << roll << endl;
   cout << "Name : " << name << endl;
   cout << "Marks : " << marks << endl;
}

int main() {
   student s[3]; // array of 3 student objects
   fstream file;
   int i;

   file.open("objects.txt", ios :: out); // open file for writing
   cout << "\nWriting Student information to the file :- " << endl;
   for (i = 0; i < 3; i++) {
      s[i].getData();
      // write the object to a file
      file.write((char *)&s[i], sizeof(s[i]));
   }
   file.close(); // close the file

   file.open("objects.txt", ios :: in); // open file for reading
   cout << "\nReading Student information to the file :- " << endl;
   for (i = 0; i < 3; i++) {
      // read an object from a file
      file.read((char *)&s[i], sizeof(s[i]));
      s[i].displayData();
   }
   file.close(); // close the file

   return 0;
}
Run this program in your system to perform read-write operations on a file  

Whenever we are taking input from console, we press "enter" key. This leads to a newline character being inserted in the input buffer. cin ignores this character to take further inputs but cin.getline( ) doesn't ignore it. Thus, we need to use the function cin.ignore( ) otherwise, we won't be able to take further inputs.

Manipulation of file pointers
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( ). Following program illustrates random access of file using file pointer manipulation functions :

#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;
}
Run this program in your system to perform file operations  

Back | Next