Files
THE CONCEPT OF FILES
Introduction
A file is a data object whose lifetime may be greater than the lifetime of a program responsible for creating it, because it is created on secondary storage devices. It is used to store persistent data values and information. The files are used mainly for input and output of data to an external operating environment. The components of the file are called as records (this term has nothing to do with record data structure).
Types of Files
A file may be a sequential file, a direct-access file, or an indexed sequential file. A sequential file can be thought of as a linear sequence of components of the same type with no fixed maximum bound. The major operations on the sequential files are:
Open operation: When a file is to be used, it is first required to be opened. The open operation requires two operands: the name of the file and the access mode telling whether the file is to be opened for reading or writing. If the access mode is "read," then the file must exist. If the access mode is "write," then if the file already exists, that file is emptied and the file position pointer is set to the start of the file. If the file does not exist then the operating system is requested to create a new empty file with a given name. The open operation requests the information about the locations and other properties of the file from the operating system. The operating system allocates the storage for this information and for buffers, and sets the file-position pointer to the first component of the file. The runtime library of C provides an fopen(name,mode) function for it. This function returns a pointer to the internal structure called FILE (you get the definition of this structure in stdio.h). This pointer is called a file descriptor; it is used by the C program to refer to the file for reading or writing purposes.
Read operation: This operation transfers the current file component to the designated program variable. The runtime library of C provides a function fgetc(fp), where fp is a file descriptor, for fscanf(). fscanf() is similar to scanf() except that one extra parameter, fp, is required to be passed as the first parameter. The second and third parameters are the same as the first and second parameters of scanf().
Write operation: This operation transfers the contents of the designated program variable to the new component created at the current position. The runtime library of C provides a function fputc(c,fp), where fp is a file descriptor, and c is a character to be written in the file fprintf(). fprintf() is similar to printf() except that one extra parameter, fp, is required to be passed as the first parameter. The second and third parameters are the same as the first and second parameters of printf().
Close operation: This operation notifies the operating system that the file can be detached from the program and that it can deallocate the internal storage used for the file. The file generally gets closed implicitly when the program terminates without explicit action by the programmer. But when the access mode is required to be changed it is required to be closed explicitly and reopened in the new mode. The runtime library of C provides an fclose(fp) function for it.
Random Access
Each read and write operation takes place at a position in the file right after the previous one. But it is possible that you may need to read or write the file in any arbitrary order. The runtime library of C provides an fseek(fp, offset, from_where) function for this. This function forces the current position in the file, whose descriptor is fd, to move by offset bytes from either the beginning of the file, the current file pointer position, or from the end of the file, depending upon the value of from_where. The parameter from_where must have one of the values (0, 1, or 2 ) that represent three symbolic constants (defined in stdio.h) as shown in Table 17.1.
CONSTANT |
WHERE |
FILE LOCATION |
---|---|---|
SEEK_SET |
0 |
File beginning |
SEEK_CUR |
1 |
Current file pointer position |
SEEK_END |
2 |
End-of-file |
After fseek, the next operation on an update file can be either input or output.
Program
This program is designed to handle data such at rollno, name and marks of a student. In this program, the following operations are performed:
- Information on a new student is entered and stored in the student.txt file.
- The student.txt file is printed on screen on the operator's request.
- The student.txt file is sorted on the basis of marks and stored in the file marks.txt.
- Information on a student whose rollno is given is printed on screen.
- The average marks of all students are calculated.
#include int bubble(int*,int); void filewrite(); void avgmarks(); void fileprint(); void filesort(); void rollin(); /******************** SORTING FUNCTION ************************/ int bubble(int x[],int n) { int hold,j,pass,i,switched = 1; for(pass = 0; pass < n-1 && switched == 1;pass++) { switched=0; for (j=0;jx[j+1]) } switched=1; hold = x[j]; x[j] = x[j+1]; x[j+1]=hold; } } return(0); } /**************** FILE WRITING FUNCTION ***********************/ void filewrite() { int roll,ch,mark; char nam[50]; FILE *fp; clrscr(); fp = fopen("student.txt","a"); printf("ENTER ROLL NUMBER, NAME, MARKS "); ch =1; while(ch) { scanf("%d%s%d",&roll,&nam,&mark); fprintf(fp,"%d %s %d ",roll,nam,mark); printf(" press 1 to continue,0 to stop"); scanf("%d",&ch); } fclose(fp) ; } /******************** OUTPUTTING DATA ON SCREEN***************/ void fileprint() { int marks[100],rollno[100],x[100],i; char name[100][50]; FILE *fp; clrscr(); fp = fopen("student.txt","r"); i=0; printf("ROLLNO NAME MARK "); while(!feof(fp)) { fscanf(fp,"%d %s %d ",&rollno[i],&name[i],&marks[i]); printf(" %d %s %d ",rollno[i],name[i],marks[i]); i=i+1; } fclose(fp); printf(" PRESS ANY KEY"); getch(); } /******************* SORTING FILE ************************/ void filesort() { int marks[100],rollno[100],x[100],n,i,j; char name[100][50]; FILE *fp,*fm; fp = fopen("student.txt","r"); fm = fopen("marks.txt","w"); i=0; while(! feof(fp)) { fscanf(fp,"%d %s %d ",&rollno[i],&name[i],&marks[i]); x[i]= marks[i]; i=i+1; } n=i; bubble(x,n); for(i=0;i
Explanation
- This program uses the following functions for its specified operation.
int bubble(int*,int) —
This bubble sorting technique is used for file sorting.
void filewrite() —
Used to write data of a new student in "student.txt" file
void fileprint() —
Used to print information on students.
void filesort() —
Used to sort the "student.txt" files on mark basis in "marks.txt"
void rollin() —
Used to find information on a student using his roll number.
void avgmarks() —
Used to find average marks of all students.
- The filewrite() function opens the student.txt file in the append mode, and data entered is written in the same file. In the void fileprint() file, student.txt is opened in read mode and data is read from it. This data is printed on the screen.
- filesort() opens the student.txt file in read mode and the file marks.txt in write mode. The data of all students is temporarily stored in one buffer consisting of three arrays: one for rollno, the second for name and the third for marks. At the same time, marks are stored in the x[ ] array for sorting purposes. The sorting is done by bubble sort. The result of sorting is available in x[ ]. At this stage, each x[ i ] is compared with marks [ j ] . If a match is found, the data on that student is stored in the marks.txt file. This process is done for all marks.
- In this way, we get a marks.txt file that is sorted on the basis of marks. In the void rollin(), the file marks.txt is used to find the student whose roll number (rollno) is given. For every line in the file, the rollno in that file is compared with the rollno to be found. If a match exists in the file, the data on that student is printed on the screen. The avgmarks() function uses the file marks.txt. Marks of students are added to variable X, each time the file pointer is incremented. Then, the average marks (sre) is displayed on the screen.
- In main function, the switch statement is used to invoke the function related to the option given by the user.
- In this program, input consists of the rollno, marks, and name of each student.
- Output depends on the user's choice. When information on students is to be printed, the program prints the content of the student.txt file on the screen. When information is sought on the basis of the roll number, the program prints the rollno, marks, and name of each student. When the average of marks is found, it prints that.
DIRECT ACCESS FILES
Introduction
A direct access file is a file in which any single component may be accessed at random. Every component has a key value associated with it. A write operation takes a component and its key value, writes the component into the file, and stores both the key and the location of the record in a file, an index. A read operation takes the key of the desired component, searches the index to find the location of the component, and retrieves the component from the file.
Program
A complete C program implementing a direct access file is given below:
#include #include #include #define MAX 50 typedef struct { char name[10]; int key; } file_record; /* this function adds the relative address to the index for a key */ void create_index(long index[], int key, long rel_add ) { index[key] = rel_add; } /* this function writes a record to the file */ void write_rec(FILE *fp, file_record rec) { fwrite(&rec,sizeof(rec),1,fp); } void main() { long rel_add; int key; file_record frec; long index[MAX];/* an index list*/ int n,i; FILE *recfile=NULL,*ifile=NULL; /* this initializes the index list to all -1 */ for(i=0; i< MAX; i++) index[i]= (-1); recfile=fopen("mfile","w"); if(recfile == NULL) { printf("Error in opening file mfile "); exit(0); } rel_add = 0 ; do { printf( " Enter the data value and the key of the record to be added to file mfile "); scanf("%s %d",frec.name,&frec.key); while(index[frec.key] != (-1)) { printf( " A record with this key value already exist in a file enter record key value "); scanf("%s %d",frec.name,&frec.key); } create_index(index,frec.key,rel_add); write_rec(recfile,frec); rel_add = ftell(recfile); /* this sets the relative address for the next record to be the value of current file position pointer in bytes from the beginning of the file */ printf("Enter 1 to continue adding records to the file "); scanf("%d",&n); }while(n == 1); ifile=fopen("index_file","w"); if(ifile == NULL) { printf("Error in opening file index_file "); exit(0); } fwrite(index,sizeof(index),1,ifile);/*writes the complete index into the index_file */ fclose(recfile); fclose(ifile); printf("Enter 1 if you want to retrieve a record "); scanf("%d",&n); if( n == 1) { ifile=fopen("index_file","r"); if(ifile == NULL) { printf("Error in opening file index_file "); exit(0); } fread(index,sizeof(index),1,ifile); /*reads the complete index into the index list from the index_file*/ fclose(ifile); recfile=fopen("mfile","r"); if(recfile == NULL) { printf("Error in opening file mfile "); exit(0); } } printf("THE CONTENTS OF FILE IS "); while( (fread(&frec,sizeof(frec),1,recfile)) != 0) printf("%s %d ",frec.name,frec.key); do { printf("Enter the key of the record to be retrieved "); scanf("%d",&key); rel_add = index[key]; /* gets the relative address of the record from index list */ if( (fseek(recfile,rel_add,SEEK_SET))!= 0) { printf("Error "); exit(0); } fread(&frec,sizeof(frec),1,recfile); printf("The data value of the retrieved record is %s ", frec.name); printf("Enter 1 if you want to retrieve a record "); scanf("%d",&n); } while(n == 1); fclose(recfile); }
Explanation
- This program writes the names in the file. A unique integer value is assigned to every name as a key value.
- The program takes the name to be stored in the file along with its key value, writes the name and key value in the file, obtains the relative address of that record, and stores it in a list called an index. The index is organized by key value.
- When the addition process ends, it writes the complete index into an index file.
- When retrieval of names is requested, the following occurs:
- The complete index is loaded into a list index from the index file.
- The index file is used to find the relative address of the record whose key value is given.
- The current position pointer is moved to that address.
- The record is read from the file.
Example
Input and Output
1.
Enter the data value and the key of the record to be added to file mfile
logk 10
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
psd 20
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
apg 3
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
agk 5
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
kdk 34
Enter 1 to continue adding records to the file
0
Enter 1 if you want to retrieve a record
1
THE CONTENTS OF FILE IS
- 1ogk 10
- psd 20
- apg 3
- agk 5
- kdk 34
Enter the key of the record to be retrieved
5
The data value of the retrieved record is agk
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
10
The data value of the retrieved record is 1ogk
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
34
The data value of the retrieved record is kdk
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
20
The data value of the retrieved record is psd
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
10
The data value of the retrieved record is 1ogk
Enter 1 if you want to retrieve a record
0
2.
Enter the data value and the key of the record to be added to file mfile
logk 10
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
psd 20
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
kdk 20
A record with this key value already exist in a file enter record key value
kdk 30
Enter 1 to continue adding records to the file
1
Enter the data value and the key of the record to be added to file mfile
asg 10
A record with this key value already exists in a file, enter record key value
asg 15
Enter 1 to continue adding records to the file
0
Enter 1 if you want to retrieve a record
1
THE CONTENTS OF FILE IS
- logk 10
- psd 20
- kdk 30
- asg 15
Enter the key of the record to be retrieved
20
The data value of the retrieved record is psd
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
15
The data value of the retrieved record is asg
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
10
The data value of the retrieved record is logk
Enter 1 if you want to retrieve a record
1
Enter the key of the record to be retrieved
30
The data value of the retrieved record is kdk
Enter 1 if you want to retrieve a record
0
Indexed Sequential Files
An indexed sequential file is like a direct access file with the additional facility of accessing the components in a sequential manner, beginning from the position of the component selected at random. This requires the index to be ordered by key values.
Exercises
- Write a C program to implement a telephone directory. Your program should provide for retrieval of an arbitrary record, given the name of the telephone subscriber.
- Write a C program to implement a database of people. Your program should provide for retrieval of information from any arbitrary record, given the code number of the person.