codescracker


c++

C++ File Pointers and Random Access



« Previous Tutorial Next Tutorial »


Every file maintains two pointers called get_pointer (in input mode file) and put_pointer (in output mode file) which tells the current position in the file where reading or writing will takes place. (A file pointer in this context is not like a C++ pointer but it works like a book-mark in a book.). These pointers help attain random access in file. That means moving directly to any location in the file instead of moving through it sequentially.

There may be situations where random access in the best choice. For example, if you have to modify a value in record no 21, then using random access techniques, you can place the file pointer at the beginning of record 21 and then straight-way process the record. If sequential access is used, then you'll have to unnecessarily go through first twenty records in order to reach at record 21.

The seekg(), seekp(), tellg() and tellp() Functions

In C++, random access is achieved by manipulating seekg(), seekp(), tellg() and tellp() functions. The seekg() and tellg() functions allow you to set and examine the get_pointer, and the seekp() and tellp() functions perform these operations on the put_pointer.

The seekg() and tellg() functions are for input streams (ifstream) and seekp() and tellp() functions are for output streams (ofstream). However, if you use them with an fstream object then tellg() and tellp() return the same value. Also seekg() and seekp() work the same way in an fstream object. The most common forms of these functions are :

seekg() istream & seekg(long);
istream & seekg(long, seek_dir);
Form 1
Form 2
seekp() ofstream & seekp(long);
ofstream & seekp(long, seek_dir);
Form 1
Form 2
tellg() long tellg()
tellp() long tellp()

The working of seekg() & seekp() and tellg() & tellp() is just the same except that seekg() and tellg() work for ifstream objects and seekp() and tellp() work for ofstream objects. In the above table, seek_dir takes the definition enum seek_dir { beg, cur, end};.

The seekg() or seekp(), when used according to Form 1, then it moves the get_pointer or put_pointer to an absolute position. Here is an example:

ifstream fin;
ofstream fout;
:			// file opening routine
fin.seekg(30);		// will move the get_pointer (in ifstream) to byte number 30 in the file
fout.seekp(30);		// will move the put_pointer (in ofstream) to byte number 30 in the file

When seekg() or seekp() function is used according to Form 2, then it moves the get_pointer or put_pointer to a position relative to the current position, following the definition of seek_dir. Since, seek_dir is an enumeration defined in the header file iostream.h, that has the following values:

ios::beg,		// refers to the beginning of the file
ios::cur,		// refers to the current position in the file
ios::end}		// refers to the end of the file

Here is an example.

fin.seekg(30, ios::beg);	// go to byte no. 30 from beginning of file linked with fin
fin.seekg(-2, ios::cur);	// back up 2 bytes from the current position of get pointer
fin.seekg(0, ios::end);		// go to the end of the file
fin.seekg(-4, ios::end);	// backup 4 bytes from the end of the file

The functions tellg() and tellp() return the position, in terms of byte number, of put_pointer and get_pointer respectively, in an output file and input file.

C++ File Pointers and Random Access Example

Here is an example program demonstrating the concept of file pointers and random access in a C++ program:

/* C++ File Pointers and Random Access
 * This program demonstrates the concept
 * of file pointers and random access in
 * C++ */

#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

class student
{
	int rollno;
	char name[20];
	char branch[3];
	float marks;
	char grade;

	public:
		void getdata()
		{
			cout<<"Rollno: ";
			cin>>rollno;
			cout<<"Name: ";
			cin>>name;
			cout<<"Branch: ";
			cin>>branch;
			cout<<"Marks: ";
			cin>>marks;

			if(marks>=75)
			{
				grade = 'A';
			}
			else if(marks>=60)
			{
				grade = 'B';
			}
			else if(marks>=50)
			{
				grade = 'C';
			}
			else if(marks>=40)
			{
				grade = 'D';
			}
			else
			{
				grade = 'F';
			}
		}

		void putdata()
		{
			cout<<"Rollno: "<<rollno<<"\tName: "<<name<<"\n";
			cout<<"Marks: "<<marks<<"\tGrade: "<<grade<<"\n";
		}

		int getrno()
		{
			return rollno;
		}

		void modify();
}stud1, stud;

void student::modify()
{
	cout<<"Rollno: "<<rollno<<"\n";
	cout<<"Name: "<<name<<"\tBranch: "<<branch<<"\tMarks: "<<marks<<"\n";

	cout<<"Enter new details.\n";
	char nam[20]=" ", br[3]=" ";
	float mks;
	cout<<"New name:(Enter '.' to retain old one): ";
	cin>>nam;
	cout<<"New branch:(Press '.' to retain old one): ";
	cin>>br;
	cout<<"New marks:(Press -1 to retain old one): ";
	cin>>mks;

	if(strcmp(nam, ".")!=0)
	{
		strcpy(name, nam);
	}
	if(strcmp(br, ".")!=0)
	{
		strcpy(branch, br);
	}
	if(mks != -1)
	{
		marks = mks;
		if(marks>=75)
		{
			grade = 'A';
		}
		else if(marks>=60)
		{
			grade = 'B';
		}
		else if(marks>=50)
		{
			grade = 'C';
		}
		else if(marks>=40)
		{
			grade = 'D';
		}
		else
		{
			grade = 'F';
		}
	}
}

void main()
{
	clrscr();

	fstream fio("marks.dat", ios::in | ios::out);
	char ans='y';
	while(ans=='y' || ans=='Y')
	{
		stud1.getdata();
		fio.write((char *)&stud1, sizeof(stud1));
		cout<<"Record added to the file\n";
		cout<<"\nWant to enter more ? (y/n)..";
		cin>>ans;
	}

	clrscr();
	int rno;
	long pos;
	char found='f';

	cout<<"Enter rollno of student whose record is to be modified: ";
	cin>>rno;

	fio.seekg(0);
	while(!fio.eof())
	{
		pos = fio.tellg();
		fio.read((char *)&stud1, sizeof(stud1));
		if(stud1.getrno() == rno)
		{
			stud1.modify();
			fio.seekg(pos);
			fio.write((char *)&stud1, sizeof(stud1));
			found = 't';
			break;
		}
	}
	if(found=='f')
	{
		cout<<"\nRecord not found in the file..!!\n";
		cout<<"Press any key to exit...\n";
		getch();
		exit(2);
	}

       fio.seekg(0);
       cout<<"Now the file contains:\n";
       while(!fio.eof())
       {
		fio.read((char *)&stud, sizeof(stud));
		stud.putdata();
       }
       fio.close();
       getch();
}

Here are the sample runs of the above C++ program:

c++ file pointers and random access

After entering the 3 records, just press n, then press enter. After performing this as shown above, press ENTER and here are the sample runs after pressing the ENTER button:

c++ file pointers

Now enter the roll number of that student whose record is to be modified. Here we enter 1, and then enter the new information for that roll number as shown here in the above and below outputs:

c++ random access

« Previous Tutorial Next Tutorial »



Tools
Calculator

Quick Links
Signup - Login - Give Online Test