Hi, I'm having problem reading a sequential file, I have done some searches all without any positive result. I trying to read a sequential file, but the problem is that the last record is read doubly. Any help would be appreciate.

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

int main () {

  string identifier,name,address,firtsenrollment, dummy;
  int creditApproved;
  ifstream myfile ("Student Registration Keyboard Out.txt");
  myfile.unsetf(ios::skipws);   
  
  if (myfile.is_open())
  {
      
                                   
    while ( !myfile.eof() )
    {
     
      getline(myfile, identifier);

      getline(myfile, name);

      getline(myfile, address);
     
      getline(myfile, firtsenrollment);

      myfile >> creditApproved;
      getline(myfile,dummy);
    
      cout << identifier << endl;
      cout << name << endl;
      cout << address << endl;
      cout << firtsenrollment << endl;
      cout << creditApproved << endl;
     
    }

myfile.close();
  }

  else cout << "Unable to open file"; 

cout << "Press enter to close the window."; 
cin.ignore ( cin.rdbuf()->in_avail() );
cin.get( );
  return 0;
  
}
870-06-4143
John Phil
Stree 5 NY, 985965
08-07-06
36
515-58-5867
Smith All
SAfasfas sfsafsadf, Pakistan
08-07-06
65
323-47-6547
Way Yo
Palm, Hawwai
41-24-65
34

Dani AI

Generated

The duplicate-last-record symptom here is almost always a loop/control problem plus fragile stream state from mixing formatted extraction with getline. and correctly pointed out that testing eof() is the wrong loop control; pointed toward driving the loop by successful reads. Two extra points not shown in the thread: remove the call to unsetf(ios::skipws) (it changes how operator>> treats leading whitespace) and avoid mixing operator>> and getline unless you carefully manage the leftover newline.

A robust, easy-to-follow pattern is to read every record line-by-line and then parse the numeric field. That avoids >>/getline interactions and makes it simple to detect a partial/incomplete record:

#include <sstream>

for (;;) {
  std::string id, name, addr, firstEnroll, creditLine;
  if (!std::getline(fin, id)) break;
  if (!std::getline(fin, name) || !std::getline(fin, addr) || !std::getline(fin, firstEnroll) || !std::getline(fin, creditLine)) {
    // incomplete record — choose to warn and break
    break;
  }
  if (!creditLine.empty() && creditLine[creditLine.size()-1] == '\r') creditLine.pop_back();
  std::istringstream iss(creditLine);
  int creditApproved = 0;
  if (!(iss >> creditApproved)) {
    // handle parse error
  }
  // process record...
}

Troubleshooting tips: check for a stray blank line at the end of the file, verify the file uses the expected line endings (CRLF can leave a '\r'), and validate each read before printing. Following this pattern will remove the double-read and make the reader resilient to malformed or truncated records.

Recommended Answers

All 6 Replies

Your problem is using the wrong way to test for the end of a file:

while ( !myfile.eof() )

See this ( feof() is the same as using .eof() )

commented: A nice link of traps to avoid +11

You are testing the eof before having read anything. What happens if your file is empty (0 length)?

To properly use the eof() method, you must read something before the loop test, then read that element as the last action in your loop body, similar to:

getline( myfile, identifier);
while( !myfile.eof( ) )
{
//get other lines of input
//process data
getline( myfile, identifier );
}

Val

>you must read something before the loop test, then read
>that element as the last action in your loop body, similar to:
What a waste of effort. How about, instead of having to figure out the order of operations and throw in redundant code to make it work, you just did this:

while ( getline ( myfile, identifier ) ) {
  // Get other lines of input
  // Process data
}

Or is that too simple for you? I understand that some people like to make everything complicated for no reason at all.

Hi, WaltP I tried your method but I was getting error with the getline and strings. The method of Narue which was I used without problem. Here is the code:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

int main () {

  string identifier,name,address,firtsenrollment, dummy;
  int creditApproved;
  ifstream myfile ("Student Registration Keyboard Out.txt");
  myfile.unsetf(ios::skipws);   
 
if (!myfile.fail())          
{                                         
[B]    while ( getline(myfile,identifier))[/B]
    {
      getline(myfile, name);
      getline(myfile, address);
      getline(myfile, firtsenrollment);
      myfile >> creditApproved;
      getline(myfile, dummy);
    
      cout << identifier << endl;
      cout << name << endl;
      cout << address << endl;
      cout << firtsenrollment << endl;
      cout << creditApproved << endl; 
    }
    
myfile.close();

}

  else cout << "Unable to open file"; 

cout << "Press enter to close the window."; 

cin.ignore ( cin.rdbuf()->in_avail() );
cin.get( );
  return 0;
    
}

For futher reference I got this link: http://mathbits.org/MathBits/CompSci/Files/End.htm

Thanks Everyone for your time! :icon_wink:

No need to get snippy.

My reply was based on OP's code and the method he chose to use, and showed how to properly use a valid technique.

Your suggestion is equally valid. Both are found in current texts.

Val

>My reply was based on OP's code and the method he chose to use
You should be encouraging good solutions rather than putting Band-Aids on bad solutions.

>Your suggestion is equally valid.
No, mine is more valid. It's easier to get right, easier to maintain, and easier to understand. Your suggestion has too many pitfalls (the OP's question was born of one) to be a viable solution at all.

>Both are found in current texts.
This is a flawed argument. I can find void main and fflush on stdin in current texts, but it doesn't make them any more valid. Now, if you show me that your solution is found in a good C++ book, by an author who is well known as an expert, your argument holds more water. The book will still be wrong, but I can forgive being mislead by a trustworthy source.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.