Chapter 4 - File Operations
Chapter 4 - File Operations
Chapter Four
Table of Contents
Introduction....................................................................................................................................................................3
Stream............................................................................................................................................................................3
Operation With File.......................................................................................................................................................3
Types of Disk File Access..............................................................................................................................................4
1: Sequential File Concepts.......................................................................................................................................4
1.1: Opening and Closing Sequential Files..........................................................................................................4
1.2: Writing to a sequential File...........................................................................................................................5
Writing characters to sequential files:.............................................................................................................5
1.3: Reading from a File.......................................................................................................................................6
Reading characters from a sequential file........................................................................................................7
1.4: File Pointer and their Manipulators...............................................................................................................7
Text Files And Binary Files (Comparison)......................................................................................................9
2: Random Access File Concepts..............................................................................................................................9
2.1 Opening Random-Access Files......................................................................................................................9
Writing randomly to a random access file.......................................................................................................9
Command Line Argument............................................................................................................................................11
Introduction
The data created by the user and assigned to variables with an assignment statement is sufficient for some
applications. With large volume of data most real-world applications use a better way of storing that data.
For this, disk files offer the solution.
When working with disk files, C++ does not have to access much RAM because C++ reads data from your
disk drive and processes the data only parts at a time.
Stream
Stream is a general name given to flow of data. In C++, there are different types of streams. Each stream is
associated with a particular class, which contains member function and definition for dealing with file. Lets
have a look at the figure:
According to the above hierarchy, the class iostream is derived from the two classes’ istream and ostream
and both istream and ostream are derived from ios. Similarly the class fstream is derived from iostream.
Generally two main header files are used iostream.h and fstream.h. The classes used for input and output to
the video display and key board are declared in the header file iostream.h and the classes used for disk file
input output are declared in fstream.h.
Note that when we include the header file fstream.h in our program then there is no need to include
iostream.h header file. Because all the classes which are in fstream.h they are derived from classes which
are in iostream.h therefore, we can use all the functions of iostream class.
Mode Description
app Opens file for appending
ate Seeks to the end of file while opening the file
in Opens the file for reading
out Opens the file for writing
binary Opens the file in binary mode
You should always check for the successful opening of a file before starting file manipulation on it. You use
the fail() function to do the task:
Lets have an example here:
ifstream indata;
indata.open("c:\\myfile.txt",ios::in);
if(indata.fail()) {
//error description here
}
In this case, the open operation will fail (i.e the fail function will return true), if there is no file named
myfile.txt in the directory C:\
After you are done with your file manipulations, you should use the close function to release any resources
that were consumed by the file operation. Here is an example
indata.close();
The above close() statement will terminate the relationship between the ifstream object indata and the file
name “c:\myfile.txt”, hence releasing any resource needed by the system.
1.2: Writing to a sequential File
The most common file I/O functions are
get() and put()
You can also use the output redirection operator (<<) to write to a file.
The following program creates a file called names.txt in C:\ and saves the name of five persons in it:
#include<fstream.h>
#include<stdlib.h>
ofstream fp;
void main() {
fp.open("c:\\names.txt" ,ios::out);
if(fp.fail()) {
cerr<< "\nError opening file";
exit(1);
}
fp<< "Abebe Alemu"<<endl;
fp<< "Lemelem Berhanu"<<endl;
fp<< "Tesfaye Mulugeta"<<endl;
fp<< "Mahlet Kebede"<<endl;
fp<< "Assefa Bogale"<<endl;
fp.close();
}//end main
outfile.open("c:\\test.txt",ios::out);
if(outfile.fail()) {
cerr<< "\nError opening test.txt";
exit(1);
}
for(int i=1;i<=15;i++) {
cout<< "\nEnter a character : ";
cin>>c;
outfile.put(c);
}
output.close();
}//end main
The above program reads 15 characters and stores in file test.txt.
You can easily add data to an existing file, or create new files, by opening the file in append access mode.
Files you open for append access mode (using ios::app) do not have to exist. If the file exists, C++ appends
data to the end of the file (as is done when you open a file for write access).
The following program adds three more names to the names.txt file created in the earlier program.
#include<fstream.h>
#include<stdlib.h>
...
void main() {
ofstream outdata;
outdata.open("c:\\names.txt",ios::app);
if(outdata.fail()) {
cerr<< "\nError opening names.txt";
exit(1);
}
outdata<< "Berhanu Teka"<<endl;
outdata<< "Zelalem Assefa"<<endl;
outdata<< "Dagim Sheferaw"<<endl;
outdata.close();
}//end main
If the file names.txt does not exist, C++ creates it and stores the three names to the file.
Basically, you have to change only the open() function’s access mode to turn a file-creation program into a
file-appending program.
1.3: Reading from a File
Files you open for read access (using ios::in) must exist already, or C++ gives you an error message. You
can’t read a file that does not exist. Open() returns zero if the file does not exist when you open it for read
access.
Another event happens when you read files. Eventually, you read all the data. Subsequently reading
produces error because there is no more data to read. C++ provides a solution to the end-of-file occurrence.
If you attempt to read a file that you have completely read the data from, C++ returns the value zero. To find
the end-of-file condition, be sure to check for zero when reading information from files.
The following code asks the user for a file name and displays the content of the file to the screen.
#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
void main() {
char name[20],filename[15];
ifstream indata;
cout<<"\nEnter the file name : ";
cin.getline(filename,15);
indata.open(filename,ios::in);
if(indata.fail()) {
cerr<<"\nError opening file : "<<filename;
exit(1);
}
void main() {
char c,filename[15];
ifstream indata;
cout<<"\nEnter the file name : ";
cin.getline(filename,15);
indata.open(filename,ios::in);
if(indata.fail()) {// check id open succeeded
cerr<<"\nError opening file : "<<filename;
exit(1);
}
while(!indata.eof()) {// check for eof
indata.get(c);
cout<<c;
}
indata.close();
}
4. tellp():
this gives the current position of put pointer (output pointer)
eg. ofstream fileout;
fileout.open(“c:\\test.txt”,ios::app);
int length = fileout.tellp();
By the above statement in length, the total number bytes of the file are assigned to the integer variable
length. Because the file is opened in append mode that means, the file pointer is the last part of the file.
Now lets see the seekg() function in action
#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
void main() {
fstream fileobj;
char ch; //holds A through Z
//open the file in both output and input mode
fileobj.open("c:\\alph.txt",ios::out|ios::in);
if(fileobj.fail()) {
cerr<<"\nError opening alph.txt";
exit(1);
}
//now write the characters to the file
for(ch = 'A'; ch <= 'Z'; ch++) {
fileobj<<ch;
}
fileobj.seekg(8L,ios::beg);//skips eight letters, points to I
fileobj>>ch;
cout<<"\nThe 8th character is : "<<ch;
fileobj.seekg(16L,ios::beg);//skips 16 letters, points to Q
fileobj>>ch;
cout<<"\nThe 16th letter is : "<<ch;
fileobj.close();
}
To point to the end of a data file, you can use the seekg() function to position the file pointer at the last byte.
This statement positions the file pointer to the last byte in the file. Fileobj.seekg(0L,ios::end);
This seekg() function literally reads “move the file pointer 0 bytes from the end of the file.” The file pointer
now points to the end-of-file marker, but you can seekg() backwards to find other data in the file.
The following program is supposed to read “c:\alph.txt” file backwards, printing each character as it skips
back in the file.
Be sure that the seekg() in the program seeks two bytes backwards from the current position, not from the
beginning or the end as the previous programs. The for loop towards the end of the program needs to
perform a “skip-two-bytes-back”, read-one-byte-forward” method to skip through the file backwards.
#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
void main() {
ifstream indata;
int ctr=0;
char inchar;
indata.open("c:\\alph.txt",ios::in);
if(indata.fail()) {
cerr<<"\nError opening alph.txt";
exit(1);
}
indata.seekg(-1L,ios::end);//points to the last byte in the file
for(ctr=0;ctr<26;ctr++) {
indata>>inchar;
indata.seekg(-2L,ios::cur);
cout<<inchar;
}
indata.close();
}
struct stud_info {
int id;
char name[20];
char fname[20];
float CGPA;
}student;
void main() {
char filename[15];
ofstream outdata;
cout<<"\nenter file name : ";
cin>>filename;
outdata.open(filename,ios::out);
if(outdata.fail()) {
cerr<<"\nError opening "<<filename;
exit(1);
}
//stud_info student;
//accept data here
cout<<"\nEnter student id : ";
cin>>student.id;
cout<<"\nEnter student name : ";
cin>>student.name;
cout<<"\nEnter student father name : ";
cin>>student.fname;
cout<<"\nEnter student CGPA : ";
cin>>student.CGPA;
//now write to the file
outdata.seekp(((student.id)-1) * sizeof(student));
outdata.write((char*) &student, sizeof(student));
outdata.close();
cout<<"\nData has been saved";
}
The above code uses the combination of ostream function seekp and write to store data at exact locations in
the file.
Function seekp sets the put file-position pointer to a specific position in the file, then the write outputs the
data.
1 is subtracted from the student id when calculating the byte location of the record. Thus, for record 1, the
file position pointer is set to the byte 0 of the file.
The istream function read inputs a specified number of bytes from the current position in the specified
stream into an object.
The syntax of read : read((char*)&name of object, sizeof(name of object));
Function read requires a first argument of type char *. The second argument of write is an integer of type
size specifying the number of bytes to be read.
Here is a code that shows how to read a random access record from a file.
#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
struct stud_info {
int studid;
char name[20];
char fname[20];
float CGPA;
};
void main() {
ifstream indata;
char filename[15];
cout<<"\nEnter the file name : ";
cin>>filename;
indata.open(filename,ios::in);
if(indata.fail()) {
cerr<<"\nError opening "<<filename;
exit(1);
}
stud_info student;
cout<<"\nEnter the id no of the student : ";
int sid;
cin>>sid;
indata.seekg((sid-1) * sizeof(student));
indata.read((char*) &student, sizeof(student));
cout<<"\nhere is the information";
cout<<"\nstudent id : "<<student.studid;
cout<<"\nstudent name : "<<student.name;
cout<<"\nstudent fname : "<<student.fname;
cout<<"\nstudent CGPA : "<<student.CGPA;
indata.close();
}
}
//now start copying the file
while(!indata.eof()) {
indata.get(ch);
outdata.put(ch);
}
indata.close();
outdata.close();
cout<<"\nfinished copying";
}
}
Finished