Brenden Carvalho
Brenden Carvalho

Reputation: 127

Getting the same output twice when reading a file

I am having a problem with the following program,

#include<iostream>
#include<fstream>
#include<windows.h>

using namespace std;

class student
{
    int rollno;
    char name[50];
    int cls;
    int marks;
    char grade;
public:
    void getdata()
    {
        cout<<"Enter Roll No.: ";
        cin>>rollno;
        cout<<"Enter Name: ";
        cin>>name;
        cout<<"Enter Class: ";
        cin>>cls;
        cout<<"Enter Marks: ";
        cin>>marks;
        if(marks>=75)
        {
            grade='A';
        }
        if(marks>=60 && marks<75)
        {
            grade='B';
        }
        if(marks>=45 && marks<60)
        {
            grade='C';
        }
        if(marks>=35 && marks<45)
        {
            grade='D';
        }
        if(marks<35)
        {
            grade='F';
        }
    }

    void display()
    {
        cout<<"\nRoll No.: "<<rollno;
        cout<<"\nName: "<<name;
        cout<<"\nClass: "<<cls;
        cout<<"\nMarks: "<<marks;
        cout<<"\nGrade: "<<grade<<endl;
    }

    int rno()
    {
        return rollno;
    }
} s1, s2, s3;

void append()
{
    fstream fo ("STUDENT.DAT",ios::binary | ios::app | ios::out);
    if(!fo)
    {
        cout<<"CANNOT OPEN FILE!!!!!";
    }

    else
    {
        s1.getdata();
        fo.write((char*)&s1, sizeof(s1));
    }
    fo.close();

}

void sdisplay()
{
    fstream fi ("STUDENT.DAT",ios::binary | ios::in);
    if(!fi)
    {
        cout<<"\nNO RECORDS !!!!";

    }
    else
    {

        while(!fi.eof())
        {
            fi.read((char*)&s2, sizeof(s2));
            if(s2.rno()!='\0')
            {
                s2.display();
            }
        }
    }
    fi.close();
}

void rdisplay()
{
    int n, found;
    fstream fi ("STUDENT.DAT", ios::in | ios::binary);
    if(!fi)
    {
        cout<<"\nNO RECORDS !!!!";
    }

    else
    {
        cout<<"\nEnter Roll No. to be displayed: ";
        cin>>n;
        while(!fi.eof())
        {
            fi.read((char*)&s3, sizeof(s3));
            if(s3.rno()==n)
            {
                s3.display();
                found=1;
            }
        }
        if(found!=1)
        {
            cout<<"\nCannot find roll no!!";
        }
    }
    fi.close();
}

int main()
{
    char ch='y';
    int choice, n;

    while(ch=='y' || ch=='Y')
    {
        cout<<"\n1. Append Data to File";
        cout<<"\n2. Display Entire File";
        cout<<"\n3. Search & Display record based on Roll No.";
        cout<<"\n4. Exit";
        cout<<"\n\n Enter your choice (1-4): ";
        cin>>choice;
        switch(choice)
        {
        case 1:
            append();
            break;

        case 2:
            sdisplay();
            break;

        case 3:
            rdisplay();
            break;
        case 4:
            exit(0);
            break;

        default:
            cout<<"\nWrong Choice !!!!!";
            break;
        }
        cout<<"\n\nDo you want to continue? (Y/N)";
        cin>>ch;
    }
}

So, After appending the data, When I go to Display the data (option 2 & 3) it outputs the same entry twice.

  1. Append Data to File
  2. Display Entire File
  3. Search & Display record based on Roll No.
  4. Exit

    Enter your choice (1-4): 2

NO RECORDS !!!!

Do you want to continue? (Y/N)y

  1. Append Data to File
  2. Display Entire File
  3. Search & Display record based on Roll No.
  4. Exit

    Enter your choice (1-4): 1 Enter Roll No.: 23 Enter Name: James Enter Class: 12 Enter Marks: 85

Do you want to continue? (Y/N)y

  1. Append Data to File
  2. Display Entire File
  3. Search & Display record based on Roll No.
  4. Exit

    Enter your choice (1-4): 2

Roll No.: 23 Name: James Class: 12 Marks: 85 Grade: A

Roll No.: 23 Name: James Class: 12 Marks: 85 Grade: A

Do you want to continue? (Y/N)n

Process returned 0 (0x0) execution time : 25.013 s Press any key to continue.

Can someone help me? Thanks

Upvotes: 0

Views: 1986

Answers (1)

Barry
Barry

Reputation: 304182

eof() won't get set until you read past the end, which won't happen until your 2nd read. That read will do nothing, so it won't overwrite s2, it'll just fail - so you'll end up printing that row again.

The solution is don't loop over eof(). Just loop over read():

while(fi.read((char*)&s2, sizeof(s2)))
{
    s2.display();
}

Upvotes: 2

Related Questions