This is a part o a bigger program. The display function is printing the last record twice. Can anyone point out my error?

#include<iostream>
#include<fstream>
#include<stdio.h>
#include<iomanip>
#include<string.h>
using namespace std;
class Hotel
{
int r_no;
char r_type[10];
float charges;
public:
void insertion();
void modify();
int getrno()
{
return r_no;
}

void getdata()
{
char ch;
cin.get(ch);
cout<<"Enter room no.-";
cin>>r_no;
cout<<"\nEnter room type-";
cin>>r_type; //use gets
cout<<"\nEnter room charges-";
cin>>charges;
}

void display()
{

cout<<r_no<<"\t\t"<<r_type<<"\t\t"<<charges<<"\n";
}
}h;

void Hotel::modify()
{
int rno;char rtype[10]; float price;char ch;
cout<<"Room No-"<<"\t"<<"Room Type"<<"\t"<<"Charges\n";
cout<<r_no<<"\t\t"<<r_type<<"\t\t"<<charges<<"\n";
cout<<"\nEnter new room number-";
cin>>rno;
cout<<"\nEnter new room type-";
cin>>rtype;
cout<<"\nEnter new room charges-";
cin>>price;
cout<<"\nRoom No-"<<"\t"<<"Room Type"<<"\t"<<"Charges\n";
cout<<rno<<"\t\t"<<rtype<<"\t\t"<<price<<"\nEnter Y to confirm changes or N to keep previous record.";
cin>>ch;
if(ch=='Y')
{
r_no=rno;
strcpy(r_type,rtype);
charges=price;
}
else
return;
}




int main()
{
int ch,i,search_rno,pos,found=0;
do
{
fstream fo;
fstream fi;
cout<<"1. Enter records \n2. Modify records\n3. Delete records\n4. Display records\nEnter choice-";
cin>>ch;
switch(ch)
{
case 1: fo.open("hotel.dat",ios::out|ios::app|ios::binary);
h.getdata();
fo.write((char*)&h,sizeof(h));
fo.close();
break;
case 3: fo.open("hotel.dat",ios::out|ios::in|ios::binary);
cout<<"\nEnter the room number of the
entry to be modified-";
cin>>search_rno;
while(!fo.eof())
{
pos=fo.tellg();
fo.read((char*)&h,sizeof(h));
if(h.getrno()==search_rno)
{
h.modify();
fo.seekg(pos);
fo.write((char*)&h,sizeof(h));
found=1;
break;
}
}
if(found=0)
cout<<"\nRecord not found";
fo.seekg(0);
break;
case 5: cout<<"Room No."<<"\t"<<"Room type"<<"\t"<<"Charges"<<"\n";
fo.open("hotel.dat",ios::in|ios::binary);
fo.clear();
fo.seekg(0,ios::beg);
while(!fo.eof())
{
fo.read((char*)&h,sizeof(h));
h.display();
}
fo.close();
break;
}
}
while(ch<=5);
return 0;
}
Don't use eof() as the condition in a loop.

You could implement the display function like this:
1
2
3
4
5
6
7
8
9
10
        case 4:   // ------------------------ Display records ---------------               
        {
            ifstream fin("hotel.dat", ios::binary);
            Hotel h;
            cout << "Room No." << "\t" << "Room type" << "\t" << "Charges" << "\n";
               
            while (fin.read(reinterpret_cast<char*>(&h), sizeof(h)))
                h.display();        
        }
            break;

I enclosed the code in braces { } so local variables can safely be used with no side-effects on other cases.

A recent thread where problems relating to eof() were discussed:
http://www.cplusplus.com/forum/beginner/223342/


Also, please use code tags - it makes your code more legible and you are more likely to get a reply:

[code]your code here[/code]

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/
Hello riona riri,

Welcome to the forum.

PLEASE ALWAYS USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/
Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.

The problem is with line 86 while (!fo.eof()). This does not work the way that you are thinking. As you can see here by the time the while condition gets the message that "eof" has been reached you have processed the last read twice. Most of the time the read is done in the while condition.

To use what you have now. Try doing the first read before the while loop and inside the while loop put the read at the bottom of the loop and "!eof" should work better.

Beyond that I would have to test the program to see how it is working.

Hope that helps,

Andy
To use what you have now. Try doing the first read before the while loop and inside the while loop put the read at the bottom of the loop and "!eof" should work better.

Rearranging the position of the read statements is a valid suggestion. But it is still better to simply test the file status, for example while( fo ) where fo is the name of the file stream.

One reason for that is there may be other problems with reading the file which means eof() does not get set at all (if a different error occurs first). Hence safer and less to unlearn to simply avoid using eof in these circumstances.
Hello riona riri,

Chervil has very good suggestions here.

I loaded up the program and changed when the read would take place and that fixed the problem for now but it is not a solution to the problem.

Hope that helps,

Andy
Topic archived. No new replies allowed.