0

I am doing a homework assignment where we are to read company data from a file and then process it for errors.

What I have so far I think will work with the first line, but I'm not sure how to make it read each line after. Each line is a record with ID, name, and payments. Basically I want to know how I can skip to the next line after I've processed the first. I haven't included the error checking yet but I think it will be in the last do while loop after 1 record is read. If the information read into each variable is wrong I can check it and output it to either the summary file or error file.

void processFile()
{
  string filename;
  ifstream recordFile;
  ofstream summary("summary.dat");
  ofstream error("error.dat");

 cout << "Please enter a filename\n";

 do
 {
    cin >> filename;
    recordFile.open(filename);
    if (!recordFile.is_open())
    cout << "No file by that name. Please enter another filename\n";  
 }
 while(!recordFile.is_open());

 int ID = 0;
 string firstName;
 string lastName;
 double payment1, payment2, payment3 = (0.00, 0.00, 0.00);
 string numberOfRecords;
 getline(recordFile, numberOfRecords);

 do
 {
     ws(recordFile);
     recordFile >> ID;
     recordFile >> firstName;
     recordFile >> lastName;
     recordFile >> payment1;
     recordFile >> payment2;
     recordFile >> payment3;

 }
 while(!recordFile.eof());
}

*edit : I found part of my problem, I actually need to skip the first line and read on from that point. The first line in each file has useless data in it.

sircrisp
  • 1,037
  • 4
  • 17
  • 32
  • Have you tried running the program to see if what you already have will work? Don't guess if something will work, try it and see what happens. – cdhowie Oct 09 '12 at 16:31
  • I did but I ran into an infinite loop of the last do while loop and it just keeps reading the first line. – sircrisp Oct 09 '12 at 16:32

2 Answers2

1

Use the getline function on the ifstream object

Raj
  • 4,342
  • 9
  • 40
  • 45
  • This is what I ended up doing to skip the first line of the file. I'm not sure if you meant I should be using it to fill the rest of the variables. I'm still a novice at this! – sircrisp Oct 09 '12 at 16:46
0

Two things. The first is if you're going to have to read multiple records, and each record is a new line, the best solution is almost always to read line by line, using std::getline, and then use std::istringstream to break up the line (record) into the desired fields. This has the advantage of keeping your input synchronized, even in case of errors; you don't have to worry about how much to skp ahead or ignore.

The second point is that you're checking for eof(). This is almost always an error; sometimes, it will lead you to reading one line too many, and in other cases, of ignoring the last line or field. If the input is successful (and you can only check for end of file after trying to input beyond it), the stream will behave as true in a conditional context; if not, it will behave as false. So your loop should be:

std::string line;
while ( std::getline( recordFile, line ) ) {
    std::istringstream record( line );
    record >> ID;
    if ( ! record ) ...
    //  ...
}

And one final comment: all of the >> operators strip leading spaces, so you don't need your call to ws. On the other hand, with the above schema, you might want to do something like:

if ( record >> ws && record.get() != EOF ) {
    //  Unexpected garbage at end of line...
}

at the very end of your loop, to verify that there isn't extra text.

James Kanze
  • 150,581
  • 18
  • 184
  • 329