Solve Endless Loop C++ File Problem | Banac.dat

  • Context: C/C++ 
  • Thread starter Thread starter chaoseverlasting
  • Start date Start date
  • Tags Tags
    C++ File
Click For Summary

Discussion Overview

The discussion revolves around a C++ programming issue where a user is experiencing an endless loop while attempting to read records from a binary file (Banac.dat). The focus is on identifying the cause of the loop and suggesting improvements to the code, particularly in the context of file reading operations.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant suggests changing the loop condition from "while (!file)" to "while (!file.eof())" to properly detect the end of the file.
  • Another participant points out that checking for end-of-file (eof) does not occur until after an attempt to read past the end of the file has been made.
  • A different participant emphasizes the importance of checking how many bytes were read and warns against using "!file" as a condition, as it may not accurately reflect the reading status.
  • There is a suggestion to store the return value of the read operation in a variable to verify if any bytes are being read at all.
  • Some participants discuss the implications of using side-effects in loop conditions and propose alternative loop structures to avoid this practice.

Areas of Agreement / Disagreement

Participants express differing views on the best practices for reading from files in C++. While there are multiple suggestions for correcting the loop, there is no consensus on a single solution, and the discussion remains unresolved regarding the optimal approach.

Contextual Notes

Participants note that the practice of dumping binary data into an object's data space may lead to issues due to variations in object size influenced by compiler options and other factors.

chaoseverlasting
Messages
1,051
Reaction score
3
Hi, I am trying to display all the records stored in a file(Banac.dat) but the program keeps on returning the first record over and over again in an endless loop ( i think its endless). If anyone could help me, it would be appreciated.

For the sake of simplicity, I've only included the errenous function and the class definition, if anyone wants to see the whole program, just ask.

Code:
#include<fstream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>char ch;
int ac=0;
int flag=0;
int acn;
float bal;

class account{
    private:
        char name[20], address[20], dob[10], type[2];
        float balance;
        int acno;
    public:
        account(float b=0):balance(b){};
        void create();         
        void close();          
      
        void withdrawal();    
        void deposit();       
      
        void report();        
        void search();         
        void disp();           
    };fstream file;void account::report()
{
    clrscr();
    file.open("Banac.dat", ios::binary|ios::in);
    while(!file)
    {
        file.read((char *)this, sizeof(account));
        disp();
        count<<endl<<endl;
    }
    getch();
    file.close();
}            //End of void report();
 
Last edited by a moderator:
Technology news on Phys.org
...did you mean "while (!file.eof())"?

(I should also mention that dumping binary data into an object's data space is generally regarded as a very poor programming practice, even if it works in this situation. Many things can affect the actual size of an object, including virtual functions, compiler options, etc.)

- Warren
 
Last edited:
read tells you how many bytes it read. You should always check how many bytes you read. :smile:

!file will only be false when an i/o operation has failed.

IIRC, if you're doing something like reading in characters one at a time, it will cause a failure if you try to read past the end of file, and so this test works.

However, read will happily read in zero bytes of data, and return successfully.
 
In C++, you cannot detect the end of file before you go past it. eof() does not return "true" until after you have tried to read past the end of file, and failed.

I've never used the read() member function myself, but I strongly suspect that your loop should be as follows, based on my experience with other input operations in C++, which evaluate as true/false in a Boolean context, indicating whether the operation succeeded or not.

Code:
while (file.read ((char *)this, sizeof(account)))
{
    disp ();
    cout << endl << endl;
}
 
Thank you for checking out my problem. I've tried the solutions offered but though it displays the first record, it keeps on displaying it over and over again. If it is bad programming practice, could you please offer me an alternative solution or point out how I may improve upon the current function.
 
jtbell,

Putting statements in your while loop condition which result in side-effects (i.e. which result in variables changing state) is also considered a very bad programming practice.

chaoseverlasting,

Try storing the return value of read() in a variable, and then printing it out. This way you can see if each call to read() is, in fact, reading any bytes at all.

- Warren
 
chroot said:
Putting statements in your while loop condition which result in side-effects (i.e. which result in variables changing state) is also considered a very bad programming practice.

Nevertheless, it is a very common idiom for input loops in C++. All the C++ input functions and operations (so far as I know) are designed so that they can be used like this. Most of the textbooks that I looked at just now, use this technique. If you want to avoid it, the simplest method is probably to use an "infinite" loop with a "break" statement:

Code:
while (true)
{
    file.read ((char *)this, sizeof(account))
    if (file.eof()) break;
    disp ();
    cout << endl << endl;
}

Otherwise, you have to do something like this:

Code:
file.read ((char *)this, sizeof(account))
while (!file.eof())
{
    disp ();
    cout << endl << endl;
    file.read ((char *)this, sizeof(account))
}

or this:

Code:
do
{
    file.read ((char *)this, sizeof(account))
    if (!file.eof())
   {
        disp ();
        cout << endl << endl;
    }
}
while (!file.eof())
 

Similar threads

Replies
6
Views
2K
  • · Replies 8 ·
Replies
8
Views
6K
Replies
10
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 75 ·
3
Replies
75
Views
7K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 9 ·
Replies
9
Views
15K
  • · Replies 1 ·
Replies
1
Views
1K