Friday, November 4, 2011

Record I/O Revisited in C programming

The record I/O program that we did in an earlier section has two disadvantages:

(a) The numbers (basic salary) would occupy more number of bytes, since the file has been opened in text mode. This is because when the file is opened in text mode, each number is stored as a character string.
(b) If the number of fields in the structure increase (say, by adding address, house rent allowance etc.), writing structures
using fprintf( ), or reading them using fscanf( ), becomes quite clumsy.
Let us now see a more efficient way of reading/writing records (structures). This makes use of two functions fread( ) and fwrite( ). We will write two programs, first one would write records to the file and the second would read these records from the file and display them on the screen.
/* Receives records from keyboard and writes them to a file in binary mode */

#include "stdio.h"
main( )
{
FILE *fp ;
char another = 'Y' ;
struct emp
{
char name[40] ;
int age ;
float bs ;
} ;
struct emp e ;
fp = fopen ( "EMP.DAT", "wb" ) ;
if ( fp == NULL )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
while ( another == 'Y' )
{

printf ( "\nEnter name, age and basic salary: " ) ;
scanf ( "%s %d %f", e.name, &e.age, &e.bs ) ;
fwrite ( &e, sizeof ( e ), 1, fp ) ;
printf ( "Add another record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
fclose ( fp ) ;
}
And here is the output...
Enter name, age and basic salary: Suresh 24 1250.50
Add another record (Y/N) Y
Enter name, age and basic salary: Ranjan 21 1300.60
Add another record (Y/N) Y
Enter name, age and basic salary: Harish 28 1400.70
Add another record (Y/N) N
Most of this program is similar to the one that we wrote earlier, which used fprintf( ) instead of fwrite( ). Note, however, that the file “EMP.DAT” has now been opened in binary mode.
The information obtained from the keyboard about the employee is placed in the structure variable e. Then, the following statement writes the structure to the file:
fwrite ( &e, sizeof ( e ), 1, fp ) ;
Here, the first argument is the address of the structure to be written to the disk.
The second argument is the size of the structure in bytes. Instead of counting the bytes occupied by the structure ourselves, we let the program do it for us by using the sizeof( ) operator. The sizeof( ) operator gives the size of the variable in bytes. This keeps the program unchanged in event of change in the elements of the structure.
The third argument is the number of such structures that we want to write at one time. In this case, we want to write only one structure at a time. Had we had an array of structures, for example, we might have wanted to write the entire array at once.
The last argument is the pointer to the file we want to write to.
Now, let us write a program to read back the records written to the disk by the previous program.
/* Reads records from binary file and displays them on VDU */

#include "stdio.h"
main( )
{
FILE *fp ;
struct emp
{
char name[40] ;
int age ;
float bs ;
} ;
struct emp e ;
fp = fopen ( "EMP.DAT", "rb" ) ;
if ( fp == NULL )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
while ( fread ( &e, sizeof ( e ), 1, fp ) == 1 )
printf ( "\n%s %d %f", e.name, e.age, e.bs ) ;
fclose ( fp ) ;
}
Here, the fread( ) function causes the data read from the disk to be placed in the structure variable e. The format of fread( ) is same as that of fwrite( ). The function fread( ) returns the number of records read. Ordinarily, this should correspond to the third argument, the number of records we asked for... 1 in this case. If we have reached the end of file, since fread( ) cannot read anything, it returns a 0. By testing for this situation, we know when to stop reading.
As you can now appreciate, any database management application in C must make use of fread( ) and fwrite( ) functions, since they store numbers more efficiently, and make writing/reading of structures quite easy. Note that even if the number of elements belonging to the structure increases, the format of fread( ) and fwrite( ) remains same.

No comments:

Post a Comment