Dremendo Tag Line

Binary File Handling in C

File Handling in C

In this lesson, we will learn how to handle binary file in C.

What is Binary File Handling

Binary File Handling is a process in which we create a file and store data in its original format. It means that if we stored an integer value in a binary file, the value will be treated as an integer rather than text.

Binary files are mainly used for storing records just as we store records in a database. It makes it easier to access or modify the records easily.

video-poster

Binary File Opening Modes

Below we have discussed the different types of binary file opening modes use to open a file.

Mode Description
rb Open file in binary mode for reading only.
wb Open file in binary mode for writing only. It creates the file if it does not exist. If the file exists, then it erases all the contents of the file.
ab Open file in binary mode for appending data. Data is added to the end of the file. It creates the file if it does not exist.
rb+ Open file in binary mode for both reading and writing.
wb+ Open file in binary mode for both reading and writing. It creates the file if it does not exist. If the file exists, then it erases all the contents of the file.
ab+ Open a file in binary mode for reading and appending data. Data is added to the end of the file. It creates the file if it does not exist.

Write primitive data, array and structure in a binary file

The program given below demonstrates how we can write primitive data, array and structure in a binary file.

Example

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

typedef struct record
{
    int roll;
    char name[20];
} record;

int main()
{
    FILE *fp;

    // primitive data types
    int i=56;
    float f=45.256;
    double d=12.54863;
    char c='d';

    // array
    int arr[3]= {15,74,29};

    // structure
    record x;
    x.roll=1;
    strcpy(x.name,"Peter");

    fp = fopen("e:/data.txt", "wb");
    if(fp == NULL)
    {
        printf("Cannot open file");
        exit(0) ;
    }

    // writing primitive data types to binary file
    fwrite(&i, sizeof(i), 1, fp);
    fwrite(&f, sizeof(f), 1, fp);
    fwrite(&d, sizeof(d), 1, fp);
    fwrite(&c, sizeof(c), 1, fp);

    // writing an array to binary file
    fwrite(&arr, sizeof(arr), 1, fp);

    // writing a structure to binary file
    fwrite(&x, sizeof(x), 1, fp);

    fclose(fp);
    return 0;
}

In the above program, we have written the primitive data type, an integer array and a structure in a binary file using the fwrite() function. This function is used to write data to a binary file. Its syntax is given below.

fwrite() Syntax

fwrite(data_address, data_size, number_of_item, file_pointer);
  • data_address: Points to the memory address of the data items to be written in a binary file.
  • data_size: It specifies the number of bytes of the data item to be written in a binary file.
  • number_of_item: It is the number of data items to be written in a binary file. 1 means the entire data item.
  • file_pointer: It is a pointer to the binary file where data items will be written.

Read primitive data, array and structure from a binary file

The program given below demonstrates how we can read primitive data, array and structure that we have written previously in a binary file.

Example

#include <stdio.h>
#include <conio.h>

typedef struct record
{
    int roll;
    char name[20];
} record;

int main()
{
    FILE *fp;

    // primitive data types
    int i;
    float f;
    double d;
    char c;

    // array
    int arr[3];

    // structure
    record x;

    fp = fopen("e:/data.txt", "rb");
    if(fp == NULL)
    {
        printf("Cannot open file");
        exit(0) ;
    }

    // reading primitive data types from binary file
    fread(&i, sizeof(i), 1, fp);
    fread(&f, sizeof(f), 1, fp);
    fread(&d, sizeof(d), 1, fp);
    fread(&c, sizeof(c), 1, fp);

    // reading an array from binary file
    fread(&arr, sizeof(arr), 1, fp);

    // reading a structure from binary file
    fread(&x, sizeof(x), 1, fp);

    // display the data on the screen
    printf("i=%d\n",i);
    printf("f=%f\n",f);
    printf("d=%lf\n",d);
    printf("c=%c\n\n",c);

    for(i=0; i<3; i++)
    {
        printf("%d ",arr[i]);
    }

    printf("\n\nRoll=%d\n",x.roll);
    printf("Name=%s",x.name);

    fclose(fp);
    return 0;
}

In the above program, we read the primitive data type, an integer array and a structure in its respective written order from the binary file using the fread() function. Its syntax is similar to fwrite() function.

File Pointer Movements

We can move file pointer associated with a file to a specific position in the file using the function fseek(). The syntax of the function is given below.

fseek() Syntax

fseek(file_pointer, number_of_bytes, from_position);
  • file_pointer: It is a file pointer that points to a file in the memory.
  • number_of_bytes: It specifies the number of bytes the file pointer should move forward in the file. Negative value moves the file pointer backward.
  • from_position: It specifies the position in the file from where the file pointer should move forward or backward. There are three types of position and they are:
    SEEK_END: It place the pointer to the end of the file.
    SEEK_SET: It place the pointer to the beginning of the file.
    SEEK_CUR: It moves the pointer from its current position in the file.

Example

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


int main()
{
    FILE *fp;
    char str[50];
    fp = fopen("e:/data.txt", "w+");
    if(fp == NULL)
    {
        printf("Cannot open file");
        exit(0) ;
    }

    // writing some text in the file
    fputs("I am learning C Programming from dremendo.com",fp);

    // move the file pointer from the beginning of the file to 5th character
    fseek(fp,5,SEEK_SET);

    // now read 10 characters including null from the current position of the file pointer
    fgets(str,10,fp);

    // print the text on the screen
    puts(str);

    // now move the file pointer 11 charaters backward from its current location
    fseek(fp,-11,SEEK_CUR);

    // now read 3 characters including null from the current position of the file pointer
    fgets(str,3,fp);

    // print the text on the screen
    puts(str);

    // now print the last 3 characters from end of the file
    fseek(fp,-3,SEEK_END);
    fgets(str,4,fp);
    puts(str);

    fclose(fp);
    return 0;
}

Output

learning
am
com

rewind() Function

The rewind() function is used to move the file pointer to the beginning of the file. See the example given below.

Example

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


int main()
{
    FILE *fp;
    char str[50];
    fp = fopen("e:/data.txt", "w+");
    if(fp == NULL)
    {
        printf("Cannot open file");
        exit(0) ;
    }

    // writing some text in the file
    fputs("I am learning C Programming from dremendo.com",fp);

    // move the file pointer to the beginning of the file using rewind()
    rewind(fp);

    // now read 15 characters including null from the current position of the file pointer
    fgets(str,15,fp);

    // print the text on the screen
    puts(str);

    fclose(fp);
    return 0;
}

Output

I am learning

Database using Binary File

The program given below shows us how we can create and manage a database of records using a binary file.

Example

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

typedef struct emp
{
    char name[40];
    int age;
    float salary;
} emp;

int main()
{
    FILE *fp, *ft;
    char another, choice;
    int f;

    emp e;
    char empname[40];
    long int esize=sizeof(e);

    // create the file if it does not exist
    fp = fopen("D:/record.txt", "ab");
    if(fp == NULL)
    {
        puts("Cannot create file");
        exit(0) ;
    }
    fclose(fp);


    // now open the file in binary mode for both reading and writing
    fp = fopen("D:/record.txt", "rb+");
    if(fp == NULL)
    {
        puts("Cannot open file");
        exit(0) ;
    }

    while(1)
    {
        //clrscr(); // clears the screen and this function work with borland compiler
        system("cls"); // clears the screen and this function work with gcc compiler
        printf("1. Add Records\n");
        printf("2. List Records\n");
        printf("3. Modify Records\n");
        printf("4. Delete Records\n");
        printf("5. Search Record\n");
        printf("0. Exit\n");
        printf("Enter Your Choice : ");
        fflush(stdin);
        choice = getche();
        getch();

        switch(choice)
        {
            case '1' :
                fseek(fp, 0, SEEK_END) ;
                another = 'Y' ;
                while(another == 'Y' || another=='y')
                {
                    printf("\n\nEnter Name: ");
                    scanf("%s", e.name);
                    printf("Enter Age: ");
                    scanf("%d", &e.age);
                    printf("Enter Salary: ");
                    scanf("%f", &e.salary);
                    fwrite(&e, esize, 1, fp);
                    printf("\nAdd another Record (Y/N) ");
                    fflush(stdin);
                    another = getche();
                }
                break;

            case '2':
                rewind(fp);
                f=0;
                printf("\n\nNAME\t\t\tAGE\tSALARY\n");
                while(fread(&e, esize, 1, fp) == 1)
                {
                    f=1;
                    printf("%s\t\t\t%d\t%.2f\n", e.name, e.age, e.salary);
                }
                if(f==0)
                {
                    printf("\nRecord does not exist\n");
                }
                getch();
                break;

            case '3' :
                another = 'Y';
                while(another == 'Y' || another=='y')
                {
                    f=0;
                    printf("\n\nEnter name of employee to modify : ");
                    scanf("%s", empname);
                    rewind(fp);
                    while(fread(&e, esize, 1, fp) == 1)
                    {
                        if(strcmpi(e.name, empname) == 0)
                        {
                            f=1;
                            printf("Record found enter new details\n\n");
                            printf("Enter Name: ");
                            scanf("%s", e.name);
                            printf("Enter Age: ");
                            scanf("%d", &e.age);
                            printf("Enter Salary: ");
                            scanf("%f", &e.salary);
                            fseek(fp, -esize, SEEK_CUR);
                            fwrite(&e, esize, 1, fp);
                            break;
                        }
                    }
                    if(f==0)
                    {
                        printf("Record not found\n");
                    }
                    printf("\nModify another Record (Y/N) ");
                    fflush(stdin);
                    another = getche();
                }
                break;

            case '4':
                another = 'Y';
                while(another == 'Y' || another=='y')
                {
                    f=0;
                    printf("\nEnter name of employee to delete : ");
                    scanf("%s", empname);
                    ft = fopen("D:/temp.txt", "wb");
                    rewind(fp);
                    while(fread(&e, esize, 1, fp) == 1)
                    {
                        if(strcmpi(e.name, empname) != 0)
                        {
                            fwrite(&e, esize, 1, ft);
                        }
                        else
                        {
                            f=1;
                        }
                    }

                    if(f==0)
                    {
                        printf("Record Not found");
                        fclose(ft);
                        remove("D:/temp.txt");
                    }
                    else
                    {
                        fclose(fp);
                        fclose(ft);
                        remove("D:/record.txt");
                        rename("D:/temp.txt", "D:/record.txt");
                        fp = fopen("D:/record.txt", "rb+");
                        printf("Delete another Record (Y/N) ");
                    }
                    fflush(stdin);
                    another = getche();
                }
                break;

            case '5' :
                another = 'Y';
                while(another == 'Y' || another=='y')
                {
                    f=0;
                    printf("\nEnter name of employee to modify ");
                    scanf("%s", empname);
                    rewind(fp);
                    while(fread(&e, esize, 1, fp) == 1)
                    {
                        if(strcmpi(e.name, empname) == 0)
                        {
                            printf("%s %d %.2f", e.name, e.age, e.salary);
                            f=1;
                            break;
                        }
                    }
                    if(f==0)
                    {
                        printf("Record not found\n");
                    }
                    printf("\nSearch another Record (Y/N) ");
                    fflush(stdin);
                    another = getche();
                }
                break;

            case '0' :
                fclose(fp);
                exit(0);
        }
    }
}

The getche() function waits until we input a character from the keyboard. It also displays the input character on the screen.

The fflush(stdin) function clears the previous data from the input buffer. The input buffer is a temporary variable where data are stored before it moves to the memory.