In our previous article, we have used “getrecord
” function. We will start this article with this function. We have to implement “getrecord” to fetch a record from the “employee.dat” file.
It will check the “employee.dat” file for an employee record based on the given employee number. If it finds the employee record it will return the employee record and the position of the record in the file; if the record is not found it will return “-1”. Below is the code forย “getrecord” function:
// getrecord function - This will search for the employee record based on // the employee number. If it finds, it will return the employee record and // also return the position where the record stored in the file. The position // is the offset from the begining of the file. // long getrecord(int empid, struct Employee *pemp) { size_t size = 0; long position = -1; // ERROR: Something went wrong. // Open the file "employee.dat" in read-only binary mode. FILE *fp = fopen("employee.dat", "rb"); if ( fp == NULL ) return position; // Fetch the records. do { size = fread(pemp, sizeof(*pemp), 1, fp); if ( pemp->ID == empid ) { position = ftell(fp); position -= sizeof(*pemp); break; } } while ( size > 0 ); // Close the file. fclose(fp); return position; }
From the above code, we have opened the file “employee.dat” in read-write binary mode. Then fetch each record from the “employee.dat” file and check whether the employee ID is matched with the given employee ID. If it is matched, the function will store the position of the record and it will return the position. Observe that, ftell function is used within “getrecord” function.
ftell
function
ftell function returns the current position of the file position indicator. Whenever fread reads the record from the file, the file position indicator will move to the next position. If the read record is what we are looking for, we need to recalculate the position of the record. The following statement will do this:
position -= sizeof(*pemp);
This tells to decrease the position value by the size of an employee record. Because after fread, the file position indicator advanced to the size of an employee record. If this is the record we are looking for, we need to adjust the position. Hence above logic. Remember that each employee record is in a fixed size.
fflush
function
Another function we used in our previous article, is fflush. fflush actually flushes the buffers for the given file pointer. Usually, the buffered functions will flush the data, once its buffers are full. To flush the buffers explicitly; we use fflush function.
Now, this is the time to show the whole code. Here it is: I put comments wherever required; hope no other explanation is required.
//employee.c #include <stdio.h> #include <stdlib.h> // Employee structure struct Employee { char Name[50]; int ID; int Age; float Salary; }; // getrecord function - This will search for the employee record based on // the employee number. If it finds, it will return the employee record and // also return the position where the record stored in the file. The position // is the offset from the beginning of the file. // long getrecord(int empid, struct Employee *pemp) { size_t size = 0; long position = -1; // ERROR: Something went wrong. // Open the file "employee.dat" in read-only binary mode. FILE *fp = fopen("employee.dat", "rb"); if ( fp == NULL ) return position; // Fetch the records. do { size = fread(pemp, sizeof(*pemp), 1, fp); if ( pemp->ID == empid ) { position = ftell(fp); position -= sizeof(*pemp); break; } } while ( size > 0 ); // Close the file. fclose(fp); return position; } // main function // void main() { // Open the file "employee.dat" in read and write binary mode. // File must be exist, otherwise the function call will fail. FILE *fp = fopen("employee.dat", "rb+"); if ( fp == NULL ) { printf("ERROR: Unable to Open the file \"employee.dat\".\n"); exit(0); } int option = 0; // Take inputs from the user do { printf("Enter your option here:\n"); printf("1. Add/Update Employee Record.\n"); printf("2. Fetch Employee Record.\n"); printf("3. Quit.\n"); scanf("%d", &option); switch ( option ) { // Add/Update Employee Record. case 1: { struct Employee emp; printf("Enter Employee Name:\n"); scanf("%s", emp.Name); printf("Enter Employee ID:\n"); scanf("%d", &emp.ID); printf("Enter Age of Employee:\n"); scanf("%d", &emp.Age); printf("Enter Employee's Salary:\n"); scanf("%f", &emp.Salary); struct Employee temp; long position = getrecord(emp.ID, &temp); if ( position >= 0 ) fseek(fp, position, 0); else fseek(fp, 0L, SEEK_END); fwrite(&emp, sizeof(emp), 1, fp); fflush(fp); } break; // Fetch Employee Record. case 2: { int empid = -1; printf("Enter Employee ID to fetch the details:\n"); scanf("%d", &empid); struct Employee emp; long position = getrecord(empid, &emp); if ( position != -1 ) { printf("Below are the requested Employee's details:\n"); printf("\t> Employee Name: %s\n", emp.Name); printf("\t> Employee ID: %d\n", emp.ID); printf("\t> Employee Age: %d\n", emp.Age); printf("\t> Employee's Salary: $%.2f\n", emp.Salary); } else printf("ERROR: Employee Record doesn't exists.\n"); } break; // Prepare for Quit. Do nothing. case 3: break; // Invalid input. default: { printf("WARNING! Invalid option.\n"); } } } while ( option != 3 ); // Close the file fclose(fp); }
I have tested the above code on my system (CentOS 64 bit), and it worked fine for me. ๐
Still, you have questions… Post them here… I will try to address them as early as I can…
We will discuss a few more file-related functions in our next articles…
// Malin
2 thoughts on “C Programming – Dealing with files – How to fetch a record from the file?”