any serious database management application, we will have to combine all that we have learnt in a proper manner to make sense. I have attempted to do this in the following menu driven program. There is a provision to Add, Modify, List and Delete records, the operations that are imperative in any database management. Following comments would help you in understanding the program easily:
- Addition of records must always take place at the end of existing records in the file, much in the same way you would add new records in a register manually.
- Listing records means displaying the existing records on the screen. Naturally, records should be listed from first record to last record.
- While modifying records, first we must ask the user which record he intends to modify. Instead of asking the record
- Addition of records must always take place at the end of existing records in the file, much in the same way you would add new records in a register manually.
- Listing records means displaying the existing records on the screen. Naturally, records should be listed from first record to last record.
- While modifying records, first we must ask the user which record he intends to modify. Instead of asking the record
number to be modified, it would be more meaningful to ask for the name of the employee whose record is to be modified. On modifying the record, the existing record gets overwritten by the new record.
− In deleting records, except for the record to be deleted, rest of the records must first be written to a temporary file, then the original file must be deleted, and the temporary file must be renamed back to original.
− Observe carefully the way the file has been opened, first for reading & writing, and if this fails (the first time you run this program it would certainly fail, because that time the file is not existing), for writing and reading. It is imperative that the file should be opened in binary mode.
− Note that the file is being opened only once and closed only once, which is quite logical.
− clrscr( ) function clears the contents of the screen and gotoxy( ) places the cursor at appropriate position on the screen. The parameters passed to gotoxy( ) are column number followed by row number.
Given below is the complete listing of the program.
/* A menu-driven program for elementary database management */
− In deleting records, except for the record to be deleted, rest of the records must first be written to a temporary file, then the original file must be deleted, and the temporary file must be renamed back to original.
− Observe carefully the way the file has been opened, first for reading & writing, and if this fails (the first time you run this program it would certainly fail, because that time the file is not existing), for writing and reading. It is imperative that the file should be opened in binary mode.
− Note that the file is being opened only once and closed only once, which is quite logical.
− clrscr( ) function clears the contents of the screen and gotoxy( ) places the cursor at appropriate position on the screen. The parameters passed to gotoxy( ) are column number followed by row number.
Given below is the complete listing of the program.
/* A menu-driven program for elementary database management */
#include "stdio.h"
main( )
{
FILE *fp, *ft ;
char another, choice ;
struct emp
{
char name[40] ;
int age ;
float bs ;
} ;
struct emp e ;
char empname[40] ;
long int recsize ;
fp = fopen ( "EMP.DAT", "rb+" ) ;
if ( fp == NULL )
{
fp = fopen ( "EMP.DAT", "wb+" ) ;
if ( fp == NULL )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
}
recsize = sizeof ( e ) ;
while ( 1 )
{
clrscr( ) ;
gotoxy ( 30, 10 ) ;
printf ( "1. Add Records" ) ;
gotoxy ( 30, 12 ) ;
printf ( "2. List Records" ) ;
gotoxy ( 30, 14 ) ;
printf ( "3. Modify Records" ) ;
gotoxy ( 30, 16 ) ;
printf ( "4. Delete Records" ) ;
gotoxy ( 30, 18 ) ;
printf ( "0. Exit" ) ;
gotoxy ( 30, 20 ) ;
printf ( "Your choice" ) ;
fflush ( stdin ) ;
choice = getche( ) ;
char empname[40] ;
long int recsize ;
fp = fopen ( "EMP.DAT", "rb+" ) ;
if ( fp == NULL )
{
fp = fopen ( "EMP.DAT", "wb+" ) ;
if ( fp == NULL )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
}
recsize = sizeof ( e ) ;
while ( 1 )
{
clrscr( ) ;
gotoxy ( 30, 10 ) ;
printf ( "1. Add Records" ) ;
gotoxy ( 30, 12 ) ;
printf ( "2. List Records" ) ;
gotoxy ( 30, 14 ) ;
printf ( "3. Modify Records" ) ;
gotoxy ( 30, 16 ) ;
printf ( "4. Delete Records" ) ;
gotoxy ( 30, 18 ) ;
printf ( "0. Exit" ) ;
gotoxy ( 30, 20 ) ;
printf ( "Your choice" ) ;
fflush ( stdin ) ;
choice = getche( ) ;
switch ( choice )
{
case '1' :
fseek ( fp, 0 , SEEK_END ) ;
another = 'Y' ;
while ( another == 'Y' )
{
printf ( "\nEnter name, age and basic sal. " ) ;
scanf ( "%s %d %f", e.name, &e.age, &e.bs ) ;
fwrite ( &e, recsize, 1, fp ) ;
printf ( "\nAdd another Record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
break ;
case '2' :
rewind ( fp ) ;
while ( fread ( &e, recsize, 1, fp ) == 1 )
printf ( "\n%s %d %f", e.name, e.age, e.bs ) ;
break ;
case '3' :
another = 'Y' ;
while ( another == 'Y' )
{
printf ( "\nEnter name of employee to modify " ) ;
scanf ( "%s", empname ) ;
rewind ( fp ) ;
while ( fread ( &e, recsize, 1, fp ) == 1 )
{
case '1' :
fseek ( fp, 0 , SEEK_END ) ;
another = 'Y' ;
while ( another == 'Y' )
{
printf ( "\nEnter name, age and basic sal. " ) ;
scanf ( "%s %d %f", e.name, &e.age, &e.bs ) ;
fwrite ( &e, recsize, 1, fp ) ;
printf ( "\nAdd another Record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
break ;
case '2' :
rewind ( fp ) ;
while ( fread ( &e, recsize, 1, fp ) == 1 )
printf ( "\n%s %d %f", e.name, e.age, e.bs ) ;
break ;
case '3' :
another = 'Y' ;
while ( another == 'Y' )
{
printf ( "\nEnter name of employee to modify " ) ;
scanf ( "%s", empname ) ;
rewind ( fp ) ;
while ( fread ( &e, recsize, 1, fp ) == 1 )
{
if ( strcmp ( e.name, empname ) == 0 )
{
printf ( "\nEnter new name, age & bs" ) ;
scanf ( "%s %d %f", e.name, &e.age,
&e.bs ) ;
fseek ( fp, - recsize, SEEK_CUR ) ;
fwrite ( &e, recsize, 1, fp ) ;
break ;
}
}
printf ( "\nModify another Record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
break ;
case '4' :
another = 'Y' ;
while ( another == 'Y' )
{
printf ( "\nEnter name of employee to delete " ) ;
scanf ( "%s", empname ) ;
ft = fopen ( "TEMP.DAT", "wb" ) ;
rewind ( fp ) ;
while ( fread ( &e, recsize, 1, fp ) == 1 )
{
if ( strcmp ( e.name, empname ) != 0 )
fwrite ( &e, recsize, 1, ft ) ;
}
fclose ( fp ) ;
fclose ( ft ) ;
if ( strcmp ( e.name, empname ) == 0 )
{
printf ( "\nEnter new name, age & bs" ) ;
scanf ( "%s %d %f", e.name, &e.age,
&e.bs ) ;
fseek ( fp, - recsize, SEEK_CUR ) ;
fwrite ( &e, recsize, 1, fp ) ;
break ;
}
}
printf ( "\nModify another Record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
break ;
case '4' :
another = 'Y' ;
while ( another == 'Y' )
{
printf ( "\nEnter name of employee to delete " ) ;
scanf ( "%s", empname ) ;
ft = fopen ( "TEMP.DAT", "wb" ) ;
rewind ( fp ) ;
while ( fread ( &e, recsize, 1, fp ) == 1 )
{
if ( strcmp ( e.name, empname ) != 0 )
fwrite ( &e, recsize, 1, ft ) ;
}
fclose ( fp ) ;
fclose ( ft ) ;
remove ( "EMP.DAT" ) ;
rename ( "TEMP.DAT", "EMP.DAT" ) ;
fp = fopen ( "EMP.DAT", "rb+" ) ;
printf ( "Delete another Record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
break ;
case '0' :
fclose ( fp ) ;
exit( ) ;
}
}
}
rename ( "TEMP.DAT", "EMP.DAT" ) ;
fp = fopen ( "EMP.DAT", "rb+" ) ;
printf ( "Delete another Record (Y/N) " ) ;
fflush ( stdin ) ;
another = getche( ) ;
}
break ;
case '0' :
fclose ( fp ) ;
exit( ) ;
}
}
}
To understand how this program works, you need to be familiar with the concept of pointers. A pointer is initiated whenever we open a file. On opening a file a pointer is set up which points to the first record in the file. To be precise this pointer is present in the structure to which the file pointer returned by fopen( ) points to. On using the functions fread( ) or fwrite( ), the pointer moves to the beginning of the next record. On closing a file the pointer is deactivated. Note that the pointer movement is of utmost importance since fread( ) always reads that record where the pointer is currently placed. Similarly, fwrite( ) always writes the record where the pointer is currently placed.
The rewind( ) function places the pointer to the beginning of the file, irrespective of where it is present right now.
The fseek( ) function lets us move the pointer from one record to another. In the program above, to move the pointer to the previous record from its current position, we used the function,
fseek ( fp, -recsize, SEEK_CUR ) ;
Here, -recsize moves the pointer back by recsize bytes from the current position. SEEK_CUR is a macro defined in “stdio.h”.
Similarly, the following fseek( ) would place the pointer beyond the last record in the file.
fseek ( fp, 0, SEEK_END ) ;
In fact -recsize or 0 are just the offsets that tell the compiler by how many bytes should the pointer be moved from a particular position. The third argument could be SEEK_END, SEEK_CUR or SEEK_SET. All these act as a reference from which the pointer should be offset. SEEK_END means move the pointer from the end of the file, SEEK_CUR means move the pointer with reference to its current position and SEEK_SET means move the pointer with reference to the beginning of the file.
If we wish to know where the pointer is positioned right now, we can use the function ftell( ). It returns this position as a long int which is an offset from the beginning of the file. The value returned by ftell( ) can be used in subsequent calls to fseek( ). A sample call to ftell( ) is shown below:
position = ftell ( fp ) ;
where position is a long int
Here, -recsize moves the pointer back by recsize bytes from the current position. SEEK_CUR is a macro defined in “stdio.h”.
Similarly, the following fseek( ) would place the pointer beyond the last record in the file.
fseek ( fp, 0, SEEK_END ) ;
In fact -recsize or 0 are just the offsets that tell the compiler by how many bytes should the pointer be moved from a particular position. The third argument could be SEEK_END, SEEK_CUR or SEEK_SET. All these act as a reference from which the pointer should be offset. SEEK_END means move the pointer from the end of the file, SEEK_CUR means move the pointer with reference to its current position and SEEK_SET means move the pointer with reference to the beginning of the file.
If we wish to know where the pointer is positioned right now, we can use the function ftell( ). It returns this position as a long int which is an offset from the beginning of the file. The value returned by ftell( ) can be used in subsequent calls to fseek( ). A sample call to ftell( ) is shown below:
position = ftell ( fp ) ;
where position is a long int
No comments:
Post a Comment