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 file opening modes use to open a binary file using the fstream class object.

Mode Description
ios::binary | ios::in This mode is used to open a file in binary mode for reading. The file pointer is placed at the beginning of the file. It is the default mode when a file is opened without any specified mode.
ios::binary | ios::out This mode is used to open a file in binary mode for writing. If the file does not exist, it will be created. If the file already exists, it will be overwritten. The file pointer is placed at the beginning of the file
ios::binary | ios::app This mode is used to open a file in binary mode for appending. If the file does not exist, it will be created. If the file already exists, all new data will be added to the end of the file.
ios::binary | ios::in | ios::out This mode is used to open a file in binary mode for both reading and writing. The file pointer is placed at the beginning of the file.
ios::binary | ios::in | ios::out | ios::trunc This mode is used to open a file in binary mode for both reading and writing, and truncates the file to zero length if it already exists. The file pointer is placed at the beginning of the file.
ios::binary | ios::in | ios::out | ios::app This mode is used to open a file in binary mode for both reading and writing, and all new data will be added to the end of the file.
ios::binary | ios::in | ios::out | ios::ate This mode is used to open a file in binary mode for both reading and writing, and the file pointer is placed at the end of the file.

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 <iostream>
#include <fstream>
#include <string.h>

using namespace std;

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

int main()
{
    // 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");

    fstream fs;
    fs.open("e:/data.txt", ios::binary | ios::out);

    if(fs.is_open()==0)
    {
        cout<<"Cannot open file";
    }
    else
    {
        // writing primitive data types to binary file
        fs.write((char*) &i, sizeof(i));
        fs.write((char*) &f, sizeof(f));
        fs.write((char*) &d, sizeof(d));
        fs.write((char*) &c, sizeof(c));

        // writing an array to binary file
        fs.write((char*) &arr, sizeof(arr));

        // writing a structure to binary file
        fs.write((char*) &x, sizeof(x));
    }

    fs.close();
    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 write() method of fstream class. This method is used to write data to a binary file. Its syntax is given below.

write() Syntax

write((char*) data_address, data_size);
  • (char*): Type cast the data to be written in the file as an array of characters.
  • 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.

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 <iostream>
#include <fstream>

using namespace std;

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

int main()
{
    // primitive data types
    int i;
    float f;
    double d;
    char c;

    // array
    int arr[3];

    // structure
    record x;

    fstream fs;
    fs.open("e:/data.txt", ios::binary | ios::in);

    if(fs.is_open()==0)
    {
        cout<<"Cannot open file";
    }
    else
    {
        // writing primitive data types to binary file
        fs.read((char*) &i, sizeof(i));
        fs.read((char*) &f, sizeof(f));
        fs.read((char*) &d, sizeof(d));
        fs.read((char*) &c, sizeof(c));

        // writing an array to binary file
        fs.read((char*) &arr, sizeof(arr));

        // writing a structure to binary file
        fs.read((char*) &x, sizeof(x));

        cout<<"Printing the primivite data"<<endl;
        cout<<"i="<<i<<endl;
        cout<<"f="<<f<<endl;
        cout<<"d="<<d<<endl;
        cout<<"c="<<c<<endl;
        cout<<"Printing the array"<<endl;
        cout<<arr[0]<<" "<<arr[1]<<" "<<arr[2]<<endl;
        cout<<"Printing the sturcture"<<endl;
        cout<<"roll="<<x.roll<<endl;
        cout<<"name="<<x.name<<endl;
    }

    fs.close();
    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 read() method of fstream class. Its syntax is similar to write() method.

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 <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

using namespace std;

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

int main()
{
    fstream fs,fs2;
    char another, choice, empname[40];
    int f;
    emp e;
    long int esize = sizeof(e);

    // create the file if it does not exist
    fs.open("E:/record.txt", ios::binary | ios::app);
    if(fs.is_open()==0)
    {
        puts("Cannot create file");
        exit(0);
    }
    fs.close();

    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
        cout<<"1. Add Records\n";
        cout<<"2. List Records\n";
        cout<<"3. Modify Records\n";
        cout<<"4. Delete Records\n";
        cout<<"5. Search Record\n";
        cout<<"0. Exit\n";
        cout<<"Enter Your Choice : ";
        fflush(stdin);
        choice = getche();
        getch();

        switch(choice)
        {
            case '1' :
                // open the file in binary mode for appending records
                fs.open("E:/record.txt",  ios::binary | ios::app);

                if(fs.is_open()==0)
                {
                    cout<<"Cannot open file";
                }
                else
                {
                    another = 'Y' ;
                    while(another == 'Y' || another=='y')
                    {
                        cout<<"\n\nEnter Name: ";
                        gets(e.name);
                        cout<<"Enter Age: ";
                        cin>>e.age;
                        cout<<"Enter Salary: ";
                        cin>>e.salary;
                        fs.write((char*) &e, sizeof(e));
                        cout<<"\nAdd another Record (Y/N) ";
                        fflush(stdin);
                        another = getche();
                    }
                }
                fs.close();
                break;

            case '2':
                // open the file in binary mode for reading records
                fs.open("E:/record.txt",  ios::binary | ios::in);

                if(fs.is_open()==0)
                {
                    cout<<"Cannot open file";
                }
                else
                {
                    f=0;
                    cout<<"\n\nNAME\t\t\tAGE\tSALARY\n";
                    while(fs.read((char*)&e, sizeof(e)))
                    {
                        f=1;
                        cout<<e.name<<"\t\t\t"<<e.age<<"\t"<<e.salary<<endl;
                    }
                    if(f==0)
                    {
                        cout<<"\nRecord does not exist\n";
                    }
                    getch();
                }
                fs.close();
                break;

            case '3' :
                // open the file in binary mode for both reading and writing records
                fs.open("E:/record.txt",  ios::binary | ios::in | ios::out);

                if(fs.is_open()==0)
                {
                    cout<<"Cannot open file";
                }
                else
                {
                    f=0;
                    cout<<"\nEnter name of employee to modify : ";
                    gets(empname);

                    while(fs.read((char*) &e, sizeof(e)))
                    {
                        if(strcmpi(e.name, empname) == 0)
                        {
                            f=1;
                            cout<<"\nRecord found enter new details\n";
                            cout<<"Enter Name: ";
                            gets(e.name);
                            cout<<"Enter Age: ";
                            cin>>e.age;
                            cout<<"Enter Salary: ";
                            cin>>e.salary;
                            fs.seekp(-esize, ios::cur);
                            fs.write((char*) &e, sizeof(e));
                            cout<<"\nRecord modified successfully";
                            break;
                        }
                    }
                    if(f==0)
                    {
                        cout<<"\nRecord not found\n";
                    }
                    getch();
                }
                fs.close();
                break;

            case '4':
                // open source file in binary mode for reading records
                fs.open("E:/record.txt",  ios::binary | ios::in);

                // open target file in binary mode for writing records
                fs2.open("E:/temp.txt",  ios::binary | ios::out);

                f=0;
                cout<<"\nEnter name of employee to delete : ";
                gets(empname);

                while(fs.read((char*) &e, sizeof(e)))
                {
                    if(strcmpi(e.name, empname) != 0)
                    {
                        fs2.write((char*) &e, sizeof(e));
                    }
                    else
                    {
                        f=1;
                    }
                }

                if(f==0)
                {
                    cout<<"\nRecord Not found";
                    fs.close();
                    fs2.close();
                    remove("E:/temp.txt");
                }
                else
                {
                    fs.close();
                    fs2.close();
                    remove("E:/record.txt");
                    rename("E:/temp.txt", "E:/record.txt");
                    cout<<"\nRecord deleted successfully";
                }
                getch();
                break;

            case '5' :
                // open file in binary mode for reading records
                fs.open("E:/record.txt",  ios::binary | ios::in);

                f=0;
                cout<<"\nEnter name of employee to search : ";
                gets(empname);

                while(fs.read((char*) &e, sizeof(e)))
                {
                    if(strcmpi(e.name, empname) == 0)
                    {
                        cout<<"\nName: "<<e.name<<endl;
                        cout<<"Age: "<<e.age<<endl;
                        cout<<"Salary: "<<e.salary;
                        f=1;
                        break;
                    }
                }
                if(f==0)
                {
                    cout<<"\nRecord not found\n";
                }
                fs.close();
                getch();
                break;

            case '0' :
                exit(0);
        }
    }
    return 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 storage area where data are stored before it moves to the memory.