File Handling in C++

File handling in C++ is not that difficult. All these times, you have been using insertion operator - << and extraction operator >> to write and read data to screen. Insertion operator uses cout object - which is an object of ostream class and extraction operator works on cin - an istream object.

ifstream is a derived class of istream  and can be used for files in read mode and ofstream is derived from ostream and is used for writing to files.

This is how you start writing to a  file
ofstream obj("myfile.txt");//constructor creates the file and opens it. 
int n;< 

 If the file can not be created or opened the object will be false.

if(!obj) cout<<"File open error" 

Another method of opening a file is a 2 step process
ifstream obj2;   obj2.open("filename"); 


Both the constructor and open method can take second parameter which is the mode of opening the file.

The mode of opening a file can be
ios::in , ios::out, ios::app, ios::trunc etc.

Writing to file:

Let us write hello world to a file.


 #include<iostream>  
 #include<fstream>  
 using namespace std;  
 int main()  
 {  
      ofstream obj("myfile.txt");  
      if(!obj)  
      {  
        cout<<"could not open file";  
           exit(1);  
      }  
      obj<<"Hello world"<<endl;  
      obj.close();  
 }  
 Voila! We wrote our first hello world file.

Reading from a file:

To read the same, we need to use an ifstream object and  extraction operator

 #include<iostream>  
 #include<fstream>  
 using namespace std;  
 int main()  
 {  
      ifstream obj("myfile.txt");  
      if(!obj)  
      {  
        cout<<"could not open file";  
           exit(1);  
      }  
      char s[100]; 
      while(obj) 
      {  
          obj>>s;  
          cout<<s;
      }
 } 
Do you notice anything stranage? There are no format specifiers anywhere and no addressof operator. That is because >> and << are overloaded for all types of data. And C++ uses reference parameters, so no addresses.

Also there are no white spaces. >> operator ignores whitespaces.

Even if you read the string from screen, the similar thing can be expected. To read a string with white spaces and everything, you can use getline function

obj.getline(str,100);

where str is character array - buffer and 100 is size of buffer.
      char str[100];
      while(obj)
      {
           obj>>str;
           cout<<str;
     } 

There is a safer version without mentioning the buffer length. This is non-member function.

getline(istream-object,char-array,delimiter)
which reads upto the delimiter character.

You can use this as


getline(obj,str,'\n');

What if you meed to read and write from the same file? That is possible too, using the mode ios::in|ios::out and using an fstream object, like this.

 int main()  
 {  
      fstream obj("myfile.txt",ios::in|ios::out);  
      if(!obj)  
      {  
        cout<<"could not open file";  
           exit(1);  }
      char s[100];
      while(obj)
      {
           obj>>s;
           cout<<s;
     } 
     obj.clear();//clear the errors on object
     obj<<"Now we write again to same file";
     obj.close();}
Do you notice some thing here? Instead of checking for NULL, we just check if the stream is true or false.

bad? fail?

Another method of checking the validity of stream is using bad(), eof() and fail() functions. bad() returns true if any invalid operation is performed on the stream. eof() returns true when end of file is reached. And fail() is true if either bad() or eof() are true.

Seek and you will find it

Remember fseek() and ftell() in C? We have equivalents here. Only we have four functions. seekg(), seekp(), tellg(), tellp(). And you are right. g is for get pointer - for reading and p is put pointer - for writing. 

seekg() and seekp() move the file pointer to the required location. They need offset as first parameter and optional seek direction as second parameter. 

     obj.clear();//clear the errors on object
     obj.seekp(0); 
     obj<<"Now we write again to same file";
     obj.close();
This code writes the line to the beginning of the file. 

tellg() and tellp() give the location of getpointer and putpointer in terms of bytes. 

Objects to a file

So far we wrote and read PODs . But we can write entire objects to the file by overloading << and extraction operators for these classes as shown below.
   class NumString
{
 int num;
 char str[40];
public:
 NumString(int n=0):num(n),str("nothing"){}
 int getNum()
 {
  return num;
 }
 void setNum(int n)
 {
  num = n;
 }
 void setstr(char *s)
 {
  strcpy(str,s);
 }
 char * getstr()
 {
  return str;
 }
};

ostream& operator << (ostream &out,NumString &obj)
{
 out<<obj.getNum()<<" "<<obj.getstr()<<"\n";
 return out;
}
 int main()  
 {  
      fstream obj("myfile.txt",ios::out);
      NumString nobj(100);
   nobj.setstr("Some string");
   obj<<nobj;
      return 0;
 }

And now we wrote our object to the file. You want to read objects from the file? Overload extraction operator!

To learn basic and advanced topics in C++ and solve quiz and write programs, you may want to download my app c++ notes


Comments

Popular Posts