File IO with Streams Many reallife problems handle

File I/O with Streams: • Many real-life problems handle large volumes of data, therefore we need to use some devices such as floppy disk or hard disk to store the data. • The data is stored in these devices using the concept of files. A file is a collection of related data stored in a particular area on the disk. • Programs can be designed to perform the read and write operations on these files. • A program typically involves either or both of the following kinds of data communication: – Data transfer between the console unit and the program. – Data transfer between the program and a disk file.

Cont. • The input/output system of C++ handles file operations which are very much similar to the console input and output operations. • It uses file streams as an interface between the programs and the files. • The stream that supplies data to the program is known as input stream and the one that receives data from the program is known as output stream. • In other words, the input stream extracts or reads data from the file and the output stream inserts or writes data to the file.

Classes for the file stream operations • The I/O system of C++ contains a set of classes that define the file handling methods. • These include ifstream, ofstream and fstream. • These classes, designed to manage the disk files, are declared in fstream. h and therefore we must include this file in any program that uses files.


Details of some useful classes Class filebuf Contents Its purpose is to set the file buffer to read and write. Contains openprot constant used in the open() of the filestream classes. Also contains close() and open() as member functions. fstreambase Provides operations common to the file streams. Serves as a base for fstream, ifstream and ofstream classes. Contains open() and close() functions. ifstream Provides input operations. Contains open() with default input mode. Inherits the functions get(), getline(), read(), seekg() and tellg() functions from istream. ofstream Provides output operations. Contains open() with default output mode. Inherits put(), seekp(), tellp(), and write() functions from ostream. fstream Provides support for simultaneous input and output operations. Contains open() with default input mode. Inherits all the functions from istream and ostream classes through iostream.

Cont. • The ifstream, ofstream and fstream classes are declared in the file fstream. h • The istream and ostream classes are also included in the fstream. h file.

Opening and closing a file • For opening a file, we must first create a file stream and than link it to the filename. • A filestream can be defined using the classes ifstream, ofstream, and fstream that are contained in the header file fstream. h • A file can be opened in two ways: – Using the constructor function of the class. This method is useful when we open only one file in the stream. – Using the member function open() of the class. This method is used when we want to manage multiple files using one stream.

Opening file using constructor • Create a file stream object to manage the stream using the appropriate class. That is, the class ofstream is used to create the output stream and the class ifstream to create the input stream. • Initialize the file object with the desired filename, e. g. : ofstream outfile(“sample. txt”); • The above statement creates an object outfile of class ofstream that manages the output stream. This statement also opens the file sample. txt and attaches it to the output stream for writing. • Similarly, the statement declared in as an ifstream object and attaches to the file “sample. txt” for reading. ifstream infile(“sample. txt”);

Single file stream working on one file Disk Output stream file outfile Program Input stream infile sample. txt

Program: Writing and reading data into file, using constructors # include <fstream. h> Opening the file sample. txt in the void main() output mode (to write the data into it) { ofstream outfile(“sample. txt”); // create file for output char ch = ‘a’; int i = 12; float f = 4356. 15; char arr[ ] = “hello”; outfile << ch << endl <<i << endl << f << endl << arr; //send the data to file outfile. close(); Closing the file, using close() method ifstream infile(“sample. txt”); Re-opening the file sample. txt in input mode (to read the data from it) infile >> ch >> i >> f >> arr; // read data from file cout << ch << i << f << arr; // send data to screen }

Opening file: • To begin with, we have defined an object called outfile of type ofstream class through the statement. ofstream outfile(“sample. txt”); • This invokes the one argument constructor of the ofstream class. • This constructor allocates resources and opens the file sample. txt. ofstream(const* char, int = ios: : out, int=filebuf: : operprot); • When we do not pass the second parameter to this constructor it uses the ios: : out as default file opening mode. • Hence the file gets opened for writing. • The third parameter corresponds to the access permission under DOS, and it is used unless ios: nocreate is specified in the file opening mode. • The default value is set to read/write permission. • Later when the file is opened for reading once again a one-argument constructor of ifstream class is invoked. This constructor uses ios: in by default to open the file for input.

Writing data: • The operator << has been overloaded in the ostream class (from which ofstream is derived). • We can use the same operator function to output data to the file as: outfile << ch << endl << i << endl << f << endl << arr << endl;

Reading data • For reading the data back we have to built an object of the istream class. • Constructor of this object opens the sample. txt file for reading.

Closing the file: • We have specifically closed the file once writing is over by calling the function close(). This is necessary since we wanted to open the same file for reading. • We have not closed the file once reading from file was over. This is because on termination of the program the infile object goes out of scope. As a result, the destructor gets called which closes the file.

Writing strings into the file: #include<fstream. h> void main() { ofstream outfile(“sample 1. txt”); // Open the file in outfile << “The rate of change ofn”; outfile << “momentum is directlyn; outfile << “proportional to the force. ”; } output mode.

Reading the strings from the file #include<fstream. h> void main() { const int MAX=80; char arr[MAX]; ifstream infile(“sample 1. txt”); // Open the file in read (input) mode while(infile) // until end of file { infile. getline(arr, MAX); // Reads first line from the file and stores cout << arr; } } // it into the array arr // Displaying the first line onto the console

Character i/o • The put() and get() functions, which are members of ostream and istream respectively, are used to output and input a single character at a time.

Example: To write data into the file, character by character. #include<fstream. h> #include<string. h> void main() { char str[]=“C++ is superset of C. It is an object-oriented / programming language. ”; ofstream outfile(“sample 2. txt”); // Open the file in write mode for(int i = 0; i < strlen(str); i++) outfile. put(str[i]); // write data into the file, character by character. }

Example: Reading characters from the file #include<fstream. h> void main() { char ch; ifstream infile(“sample 2. txt”); // Open the same file in input mode while(infile!= EOF) { inflie. get(ch); // Read the data from the file character by character the // and store the character into the variable ch cout << ch; // Display the character read, onto the screen } }

Writing and reading Objects of a class • So far we have done I/O of basic data types. Since the class objects are the central elements of C++ programming, it is quite natural that the language supports features for writing and reading from the disk files objects directly. • The binary input and output functions read() and write() are designed to do exactly this job. • The write() function is used to write the object of a class into the specified file and read() function is used to read the object of the class from the file. • Both these functions take two arguments: 1. address of object to be written. 2. size of the object. • The address of the object must be cast to the type pointer to char. • One important point to remember is that only data members are written to the disk file and the member functions are not.

Example: Writing an object into the file #include<fstream. h> class Person { private: char name[40]; int age; public: void get. Data() { cout << “n Enter name: ”; cin >> name; cout << “n Enter age: ”; cin >> age; } } ; // End of the class definition

Cont. void main() { Person per ; // Define an object of Person class per. get. Data(); // Enter the values to the data members of the class. ofstream outfile(“Person. txt”); // Open the file in output mode outfile. write((char*)&per, sizeof(per)); // Write the object into the file }
![Reading object from the file #include<fstream. h> class Student { private: char name[40]; int Reading object from the file #include<fstream. h> class Student { private: char name[40]; int](http://slidetodoc.com/presentation_image_h2/05f8c57f79b210455a32a3bd91731ee4/image-23.jpg)
Reading object from the file #include<fstream. h> class Student { private: char name[40]; int age; public: void show. Data() { cout << “n NAME = “ << name; cout << “n AGE = “ << age; } };

Cont. void main() { Student studobj; // Define an object of Student class ifstream infile(“Person. txt”); // Open the file Person. txt in read/input mode. infile. read((char*)&studobj, sizeof(studobj)); // Read the object // from the file Person. txt studobj. show. Data(); // Display the data values on the screen }
![Example: I/O with multiple objects class Person { private: char name[40]; int age; public: Example: I/O with multiple objects class Person { private: char name[40]; int age; public:](http://slidetodoc.com/presentation_image_h2/05f8c57f79b210455a32a3bd91731ee4/image-25.jpg)
Example: I/O with multiple objects class Person { private: char name[40]; int age; public: void get. Data() { cout << “n Enter name: : ; cin. get(name, 40); cout << “n Enter age: “; cin >> age; } void show. Data() { cout << “n Name =“ << name; cout << “n Age =“ << age; } } ;

Cont. void main() { char ch; Person per; fstream file; file. open(“Person. txt”, ios: : app | ios: : out | ios: : in); do { cout << “n Enter person’s data: “; per. get. Data(); file. write((char*)&per, sizeof(per)); cout << “n Enter another person (y/n)? ”; cin >> ch; } while(ch == ‘y’);

Cont. file. seekg(0); // reset to start of the file. read((char*)&per, sizeof(per)); // read the first person while(! file. eof()) { cout << “n Person: “; per. show. Data(); file. read((char*)& per, sizeof(per)); // read another // person } } // End of the main function

Cont. • fstream object can be used for both input & output. • In the open() function we include several mode bits to specify certain aspects of the file object. • app -> To preserve whatever was in the file before. Whatever we write to the file will be appended to the existing contents. • We use in and out because we want to perform both input and output on the file. • eof() is a member function of ios class. It returns a nonzero value if EOF is encountered and a zero otherwise.

Parameters of open() function Parameter ios: : app ios: : ate ios: : in ios: : nocreate ios: : noreplace ios: : out ios: : trunc Meaning Append to end of the file Go to end of the file on opening Open file for reading only Open fails if the file does not exist Open fails if the file already exists Open file for writing only Delete contents of the file if it exists

Cont. • Opening a file in ios: : out mode also opens it in the ios: : trunc mode by default. • Both ios: : app and ios: : ate take us to the end of the file when it is opened. But the difference between the two parameters is that the ios: : app allows us to add data to the end of the file only, while ios: : ate mode permits us to add data or to modify the existing data anywhere in the file. • Creating a stream using ifstream implies input and creating a stream using ofstream implies output. So in these cases it is not necessary to provide the mode parameters. • The fstream class does not provide a mode by default and thus, we must provide the mode explicitly when using an object of fstream class. • The mode can combine two or more parameters using the bitwise OR operator fstream fout ; fout. open(“data”, ios: : app | ios: : nocreate); This opens the file in the append mode but fails to open the file if it does not exist.

File pointers and their manipulations: • Each file has two associated pointers known as the file pointers. • One of them is called the input pointer or get pointer. • 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.

Default action • When we open a file in read-only mode, the input pointer is automatically set at the beginning so that we can read the file from the start. • Similarly, when we open a file in write-only mode, the existing contents are deleted and the output pointer is set at the beginning. This enables us to write to the file from the start.

Functions for manipulation of 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.

Cont. infile. seekg(10); • Moves the file pointer to the byte number 10. • The bytes in a file are numbered beginning from zero. • Thus, the pointer will be pointing to the 11 th byte in the file.

Cont. ofstream fileout; fileout. open(“sample. txt”, ios: : app); int p = fileout. tellp(); • On execution of these statements, the output pointer is moved to the end of the file “hello” and the value of p will represent the number of bytes in the file.

Specifying the offset • The seek functions seekg() and seekp() can also be used with two arguments as follows: seekg(offset, refposition); seekp(offset, refposition); • The parameter offset represents the number of bytes the file pointer to be moved from the location specified by the parameter refposition. • The refposition takes one of the following these constant defined in the ios class. ios: : beg start of the file ios: : current position of the pointer ios: : end of the file.

Sample pointer offset calls and their actions. Seek call fout. seekg(0, ios: : beg); fout. seekg(0, ios: : cur); fout. seekg(0, ios: : end); fout. seekg(m, ios: : beg); fout. seekg(m, ios: : cur); fout. seekg(-n, ios: : end); Action go to start stay at the current position go to the end of the file. move to (m+1)th byte in the file. go forward by m bytes from the current position go backward by n bytes from the end.
![Program to write objects into file class Person { private: char name[40]; int age; Program to write objects into file class Person { private: char name[40]; int age;](http://slidetodoc.com/presentation_image_h2/05f8c57f79b210455a32a3bd91731ee4/image-38.jpg)
Program to write objects into file class Person { private: char name[40]; int age; public: void get. Data() { cout << “n Enter name: : ; cin. get(name, 40); cout << “n Enter age: “; cin >> age; } } ; // End of the class definition

Cont. void main() { char ch; Person per; do // Write multiple objects into the file { cout << “n Enter person’s data: “; per. get. Data(); file. write((char*)&per, sizeof(per)); cout << “n Enter another person (y/n)? ”; cin >> ch; } while(ch == ‘y’); }

Example: This program counts the number of objects already written into the file “Person. txt”. Then is reads the nth object and displays the values of its data members. class person { private: char name[40]; int age; public: void show. Data() { cout << “n Name = “ << name; cout << “n Age = “ << age; } };

Cont. void main() { person pers; // create person object ifstream infile; // create input file infile. open(“Person. txt”); // open the file infile. seekg(0, ios: : end); // go to end from 0 byte int endposition = infile. tellg(); // find where we are int num = endposition/sizeof(person); // number of persons cout << “n There are “ << num << “ persons in file: “; int n ; cout << “n Enter record number to be displayed “; cin >> n; int position = (n-1) * sizeof(person); // number times size infile. seekg(position); infile. read( (char*)&pers, sizeof(pers) ); pers. show. Data(); // display the person }
- Slides: 41