Unit VI                    File Handling
Introduction
   • C++ supports all C’s rich set of I/O functions
   • Two reasons why we don’t use these functions in C++
      – I/O methods of C does not supports OOP
      – I/O methods of C does not handle user defined data types
        such as class object
   • C++ uses concept of stream & stream classes to
     implement I/O functions with the console and disk
     file.
                       Streams
• The I/O Stream in C++ is designed to work with a variety of
  devices including terminals, disk & tape drives.
• The I/O system supplies an interface to the programmer that
  is independent of the actual device being accessed. This
  interface is known as stream.
• A stream is a sequence of bytes. It acts either as a source
  from which the i/p data can be obtained or as a destination to
  which the o/p data can be sent.
• The source stream that provide data to the program is called
  the input stream.
• The destination stream that receives output from the program
  is called the output stream.
 • In other words, A program extracts the bytes from an input
   stream & insert bytes into output stream as illustrate in
   following fig:                                            Extraction
                            Input stream
                                                              From input
                                                              stream
Input device
                                                          Program
                             Output stream
                                                              insert
  Output
                                                              Into
  device
                                                              output
                                                              stream
                          Fig: Data Stream
• The data in Input stream can come from keyboard or any
  other storage device.
• The data in Output stream can go to screen or any other
  storage device.
                   C++ Stream classes
• The C++ system contains a hierarchy of classes that
  are used to define various streams to deal with both
  the console & disk file, these classes are called
  stream classes.
                   ios                         ios   base class
                                               ios is declared as virtual
                                              base class so only one copy of
istream                          ostream      members are inherited by
                                              iostream
                iostream
   Fig: shows hierarchy of the stream classes used for i/p & o/p operations
   with the console unit.
    Stream classes for Console Operations
         Class name                            Contents
ios                          Basic facilities that are used by all other
(general input/output stream input-output classes.
class)                       Also contain a pointer to buffer object
                             (streambuff object)
Istream                      Inherits properties of ios
(input stream)               Has functions like get( ), getline( ),
                             read( )
                             Contains overloaded operator >>
Ostream                        Inherits properties of ios
(output stream)                Put( ), write( )
                               Contains overloaded operator <<
Iostream                       Inherits properties of istream and
(input/ output stream)         ostream through multiple inheritance
                               and thus contains all input and output
                               functions
                Stream Errors
 There are many abnormal conditions while handling
  the input & output.
 When error occurred during input or output
  operations, the errors are reported by stream state.
 Every stream (istream or ostream) has a state
  associate with it.
 Error conditions are detected & handled by testing
  the state of the stream.
         Predefined Stream Objects
• The two other predefined objects are cerrand clog.
• cin: an object of istream, normally used for keyboard
  input
• cout: an object of ostream, normally used for screen
  display
• cerr: an object of ostream, for error messages
• clog: an object of ostream, for log messages
                          File
• A file is a collection of
  related data stored in a
  particular area on the disk.
  The data is stored in disk
  using the concept of file.
• The information / data
  stored under a specific
  name on a storage device,
  is called a file.
• Programs can be designed
  to perform the read and
  write operations on these
  files.
• The I/O system of C++ handles file operations which are
  similar to console i/p & o/p operations.
• It uses file streams as an interface between the program
  & files
• Input stream extract (or read) data from the file and the
  output stream inserts (or writes) data to the file.
• This is illustrated in following fig:
                              Input stream
        Read data
                                                             Data
                                                             input
  Disk File                                              Program
                               Output stream
                                                             Data
                                                             Output
     Write
     data           Fig: file input and output streams
          Disk File I/O with Stream
• Why use File Handling
  – For permanent storage.
  – The transfer of input - data or output - data from one
    computer to another can be easily done by using files.
File Stream Classes
        Functions used in File Handling
• If we want to use a disk file, we need to decide the following
  things about the file & its intended use:
1) Suitable name for the file.
2) Data type & structure
3) Purpose
4) Opening method
            Opening and Closing a File
For opening a file, first create a file stream & then link it to
  the filename.
 A file stream can be defined using the classes ifstream,
  ofstream & fstream.
 The class to be used depends upon the purpose, i.e. whether
  we want to read data from file or write data to it.
 A file can be opened in two ways:
1) Using the constructor function of the class.
2) Using the member function open( ) of the class
 The first method is useful when we use only one file in the
   stream.
 The second method is used when we want to manage
   multiple files using one stream.
        Opening a File Using Constructor
 Constructor is used to initialize an object while it is being
  constructed. Here a filename is used to initialize the file stream
  object.
The involves the following steps:
1) Create a file stream object to manage the stream using the
   appropriate class. i.e. , the class ofstream is used to create the
   output stream & the class ifstream to create the input stream.
2) Initialize the file object with the desired filename.
Example: ofstream outfile(“result”) ; // output only
This create outfile as an ofstream object that manages the output
   stream.
This object can be any C++ name such as o_file, myfile or fout.
This statement also opens the file “result” & attaches it to the
   output stream outfile.
       Opening a File Using Constructor
 similarly, following statement declares infile as an ifstream
  object and attaches it to the file “data” for reading (input)
 Example: ifstream infile(“data”) ; // input only
                                                           Disk
                          Output stream
                                                          Result
                                                           file
                          outfile
    Program
                          Input stream
                                                         Data file
                          infile
       Fig: Two file streams working on separate files
Use of same file for both reading & writing data:
The program would contain following statements:
Program1
---------
---------
Ofstream outfile( “salary”) ; //create outfile & connects “salary” to it.
 --------
---------
Program2
----------
---------
Ifstream infile (“salary”) ; //create infile & connects “salary” to it
---------
---------
     Program1                 outfile
      ----------
      ----------
                                                          Salary
                                                           file
     Program2
                             infile
      ----------
      ----------
              Fig: Two file streams working on one file
Ms
Use of single program to do both the operation on a file.
The program would contain following statements:
---------
---------
ofstream outfile(“salary”) ; //create outfile & connects “salary” to it.
 --------
---------
Outfile.close( ); //disconnect salary from outfile
ifstream infile (“salary”) ; //and connect to infile
---------
---------
Infile.close( );   //disconnect salary form infile
                 outfile
                                                  Salary
Program                                            file
                 infile
      Fig: Two file streams working on one file
        Opening a File Using Constructor
#include<iostream.h>     //console i/o
#include<fstream.h>     //file i/o
int main()
{
      ofstream outf("Student1.txt");   //write only
      cout<<"\nEnter Roll No:";
      int rno;
      cin>>rno;
      outf<<rno<<"\n";              //write to file
      outf.close();
      ifstream inf("Student1.txt"); //read only
      inf>>rno;                     //read rno from file
      inf.close();
      return 0;
}
             Opening a File Using open()
• The function open( ) can be used to open multiple files that use
  the same stream object.
• In such a cases, first create a single stream object & use it to
  open each file in turn.
• This is done as follows:
    file-stream-class stream-object ;
      Stream-object . open( “filename” , mode ) ;
Here , mode specifies the purpose for which the file is opened.
   File mode parameter                      Meaning
ios::app                  Append to end of file
ios::ate                  go to end of file on opening
ios::binary               file open in binary mode
ios::in                   open file for reading only
ios::out                  open file for writing only
ios::nocreate             open fails if the file does not exist
ios::noreplace            open fails if the file already exist
ios::trunc                delete the contents of the file if it exist
             Open and close a file
eg:-
 ofstream outfile;     // create stream
 outfile.open (“DATA1”); // connect stream to DATA1
 ……………………………..
 ……………………………..
 outfile.Close();     //disconnect stream from DATA1
 outfile.open(“DATA2”); //connect stream to DATA2
 ……………………………..
 ……………………………..
 outfile . close( );
 ……………………………..
          Opening a File Using open()
#include<iostream.h>
#include<fstream.h>
int main()
{
       ofstream fout;
       fout.open("Country");
       fout<<"US\n";
       fout<<"UK\n";
       fout.close();
      fout.open("Capital");
      fout<<"Washington\n";
      fout<<"London\n";
      fout.close();
      const int N=50;
      char line[N];
      ifstream fin;   //read only
      fin.open("Country");
      cout<<"\nContents of country file\n";
    while(fin)
    {
           fin.getline(line,N);
           cout<<line<<"\n";
    }
    fin.close();
    fin.open("Capital");
    cout<<"\nContents of Capital file \n";
    while(fin)
    {
           fin.getline(line,N);
           cout<<line<<"\n";
    }
    fin.close();
    return 0;
}
                  Detecting end-of-file
• Detection of the end of file is necessary for preventing any further
   attempt to read the data from the file.
       The statement while(fin) detect end of file.
• An ifstream object such as fin, returns a value 0 if any error occurs in
   the file operation including the enf-of-file condition.
• Thus, the while loop terminates when fin returns a value 0 on
  reaching the end-of-file condition.
• There is another approach to detect the end of file condition, the
   statement as follows:
           if (fin.eof( ) != 0)
           {   exit( 1 ) ;   }
eof( ) is a member function of ios class.
It returns non-zero value if eof condition is encountered & zero
otherwise.
            Error Handling in File I/O
• Error may occur during file operation for instance, one of
  the following things may happen when dealing with the
  files.
  1) A file which are attempting to open for reading does
  not exist.
  2) The file name used for a new file may already exist.
  3) We may attempt invalid operation such as reading
  past the end-of-file.
  4) There may not be any space in the disk for storing
  more data.
  5) We may use an invalid file name.
  6) We may attempt to perform an operation when the
  file is not opened for that purpose.
             Error Handling in File I/O
 C++ file stream inherits a “stream-state” member
  from the class ios. This member record information
  on the status of file that is being currently used.
 The stream-state member uses bit field to store the
  status of the error condition stated above.
• When error occurs in file handling, flags are set in the
  state according to general category of the error.
• Following table shows the error flags (Bit field)
                Bit Description
• ios::eof bit Set when the end of an input stream is
  encountered.
• ios::failbit Set when an attempted operation has
  failed.
• ios::hardfail Set when an unrecoverable error has
  occurred.
• ios::badbit Set when an invalid operation has been
  attempted.
• ios::goodbit Set when all the flags above are not set.
  Indicates the stream is in good condition.
          Error Handling function in files
• The class ios support several member function that can
  be used to read the status recorded in a file stream.
  The function along with their meaning are listed below.
Example: member functions for checking the state of stream
#inclued<iostream>
#include<fstream>                           Output:
int main( )                                  1) Run
{                                           Enter an integer value: a
   int val ;                                Incorrect input
   char name = ‘y’ ;                        The good() function return: 0
    cout<<“\n Enter an integer value “ ;
                                            2) Run
    cin >> val ;
                                            Enter an integer value: 10
    if(cin.good() == 0) // if error         Correct input
   {                                        The good() function return: 1
       cout<<“\n Incorrect Input” ;
     cout<<“\n The good() function returns: “ <<cin.good() ;
    }
   else
  {
     cout<<“\n Correct Input”;
     cout<<“\n The good() function returns: “<<cin.good( ) ;
  }
return 0;
}
                         File Pointer
 Each file have two associated pointers known as the file
  pointers. One of them is called the input pointer (or get
  pointer) and the other is called the output pointer (or put
  pointer).
 We can use these pointers to move through the files while
  reading or writing.
 The input pointer is used for reading the contents of a given
  file location and the output pointer is used for writing to a
  given file location.
 Each time an input or output operation takes place, the
  appropriate pointer is automatically advanced.
                   Default Action of File Pointer:
Following fig shows the action on file pointer while opening a file
     Functions for Manipulating File Pointers
 When we want to move file pointer to desired position then use these
   function to manage the file pointers.
 seekg ( ) = moves get pointer (input) to a specified location
 seekp ( ) = moves put pointer (output) to a specified location
 tellg ( )   = gives the current position of the get pointer
 tellp ( )   = gives the current position of the put pointer
Examples:
1) infile.seekg(10) ; => moves the file pointer to the byte number 10.
2) ofstream fileout ;
   fileout.open(“hello” , ios::app) ;
   int p = fileout.tellp( ) ;
On execution of these statements, the output pointer is moved to the end
   of the file “hello” & the value of p will represent the number of bytes in
   the file.
                 Specifying the offset:
 The argument to these functions (seekg, seekp) represents the
  absolute position in the file, as shown in the following fig:
 This function can also used with two arguments:
              File I/O Functions
   Function                  Operation
open( )       To create a file
close( )      To close an existing file
get( )        Read a single character from a file
put( )        write a single character in file.
read( )       Read data from file
write( )      Write data into file.
            Put( ) and get( ) functions
 • The function put() write a single character to the
   associated stream. Similarly, the function get() reads
   a single character from the associated stream.
#include<iostream.h>
#include<fstream.h>
#include<conio.h>
int main()
{
     char str[30];
     clrscr();
     cout<<"\nEnter String:";
     cin.getline(str,30);
     fstream fs;
    fs.open("Sample.txt",ios::in|ios::out);
    for(int i=0;str[i]!='\0';i++)
         fs.put(str[i]);
    cout<<"\nContents of the file:";
    char ch;
    fs.seekg(0,ios::beg);
    while(fs)
    {
         fs.get(ch);
         cout<<ch<<"\n";
    }
    getch();
    return 0;
}
          read( ) and write( ) functions
 The read( ) & write( ) functions , handled the data in binary
 form. This means that the value are stored in the file same
 format in which they are stored in internal memory.
The binary input & output functions takes following form:
        file . read ((char *)&V , sizeof (V));
        file . Write ((char *)&V , sizeof (V));
 • These function take two arguments.
 • The first is the address of the variable V , and the second is
   the length of that variable in bytes . The address of variable
   must be cast to type char * (i.e pointer to character type) .
#include<iostream.h>
#include<fstream.h>
#include<conio.h>
class Stud
{
     int rno;
     char name[10];
     int marks;
     public:
     void getdata();
     void putdata();
};
void Stud::getdata()
{
     cout<<"\nEnter Roll No:";
     cin>>rno;
     cout<<"\nEnter Name:";
     cin>>name;
     cout<<"\nEnter Marks:";
     cin>>marks;
}
void Stud::putdata()
{
     cout<<"\n"<<rno<<"\t"<<name<<"\t"<<marks;
}
int main()
{
     Stud s[5];
     fstream fs;
     fs.open("Stud1.data",ios::out|ios::binary);
     for(int i=0;i<3;i++)
     {
           s[i].getdata();
           fs.write((char *)&s[i],sizeof(s[i]));
     }
     fs.close();
    cout<<"\nDisplay contents of file";
    fs.open("Stud1.data",ios::in|ios::binary);
    Stud s1;
    fs.read((char*)&s1,sizeof(s1));
    while(fs)
    {
         s1.putdata();
         fs.read((char*)&s1,sizeof(s1));
    }
    fs.close();
    getch();
    return 0;
}
Overloading stream insertion (<<) and extraction (>>) operators
• In C++, stream insertion operator “<<” is used for output
  and extraction operator “>>” is used for input.
• We must know following things before we start
  overloading these operators.
  1) cout is an object of ostream class and cin is an object
  istream class
  2) These operators must be overloaded as a global
  function. And if we want to allow them to access private
  data members of class, we must make them friend.
                            Example
#include <iostream>
using namespace std;
class Complex
{
 private:
          int real, imag;
  public:
          Complex(int r = 0, int i =0)
          {
             real = r; imag = i;
          }
          friend ostream & operator << (ostream &out, Complex &c);
          friend istream & operator >> (istream &in, Complex &c);
};
istream & operator >> (istream &in, Complex &c)
 {
          cout << "Enter Real Part ";
          in >> c.real;
          cout << “\n Enter Imagenory Part ";
          in >> c.imag;
          return in;
}
ostream & operator << (ostream &out, Complex &c)
 {
         out << c.real;
         out << "+i" << c.imag << endl;
         return out;
}
int main( )
{
         Complex c1;
         cin >> c1;
         cout << “\n The complex object is ";
         cout << c1;
         return 0;
}
 Output:
 • Enter Real Part 10
 • Enter Imaginary Part 20
 • The complex object is 10+i20
     Command line arguments in C++
• If any input value is passed through command
  prompt at the time of running of program is known
  as command line argument.
• In Command line arguments application main()
  function will takes two arguments that is;
  – argc
  – argv
      Command line arguments in C++
• argc(argument counter): argc is an integer type
  variable and it holds total number of arguments
  which is passed into main function. It takes Number
  of arguments in the command line including program
  name.
• argv[ ](argument vector) : argv[ ] is an array of char*
  type pointer, which holds actual arguments which is
  passed to main function. The size of this array will be
  equal to the value of argc.
    Command line arguments in C++
#include<iostream>
using namespace std;
int main(int argc,char** argv)
{
     cout<<"\nARGC:"<<argc;
     for(int i=0;i<argc;i++)
     cout<<argv[i]<<"\n";
     return 0;
}
Output
          Memory as a Stream Object
 In C++, it is possible to treat particular section of memory
  as an object and data can be inserted into this section of
  memory with the help of memory object.
 The memory as a stream object is normally used when the
  formatted output is required for a c++ program.
 The stream classes ostrstream is commonly used to create
  memory object.
 The syntax for creating such memory object is:
 ostrstream object_name(data_buffer , size_of_buffer) ;
Following is the program that shows how to use memory as a
  stream object.
#include<iostream.h>
#include<iomanip.h>
#include<conio.h>
#include<strstream.h>
const int size = 20 ; // size of memory buffer
int main()
{
         int RollNo = 10;
         char name[] ="ABC";
         char data[size]; //data buffer for memory object
         clrscr();
         //create stream object by passing buffer & size
         ostrstream memobj(data,size);
         memobj<<"Roll Number ="<<RollNo<<"Name="<<name<<'\0';
         // end of buffer with ‘\0’
       cout<<data ;   //Display the data buffer
       getch();
       return 0;
}
                Printer Output
• It’s fairly easy to use console-mode programs to send
  data to the printer.
• A number of special filenames for hardware devices
  are defined by the operating system.
• These make it possible to treat the devices as if they
  were files.
• In most systems the printer is connected to the first
  parallel port, so the filename for the printer should
  be prn or lpt1.
 Form feed is a page-breaking ASCII control character. It forces the printer
to eject the current page and to continue printing at the top of another.
Ms. R