Could anyone tell me why this code read an extra line? It duplicates some of the last line, only it changes the number. For example, the text file (set up as an inventory file) reads:

45 car
23 bus
1 truck
4 van

After running the program, it displays that, but the last line it adds:

0 van

Here's the code I have so far:

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

const int SIZE = 500;

struct Inventory 
{
       int itemNumber;
       string itemName;
};

int main(int argc, char *argv[])
{   
    char filename[20];
    ifstream in_stream;
    
    struct Inventory items[SIZE];
    
    cout << "Enter a filename to load: ";
    cin >> filename;

    in_stream.open(filename);
    
    if (in_stream.fail()) {
       cout << "Failed" << endl;
       }
    else {
         cout << "File opened sucessfully." << endl;
         }
    string data, junk;
    int n = 0;
    char next_symbol, number[15];
    
    do {
        int i = 0;
        do {
            in_stream.get(next_symbol);
            number[i] = next_symbol;
            i++;
        } while (next_symbol != ' ');
        items[n].itemNumber = atoi(number);
         
        getline(in_stream, data);
        items[n].itemName = data;
      
        cout << endl << items[n].itemNumber << setw(15) << items[n].itemName;
        n++;
    } while (! in_stream.eof());
        
    in_stream.close();
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

As soon as you said this:

Could anyone tell me why this code read an extra line?

I immediately looked for this:

while (! in_stream.eof());

This is a very common problem when testing eof() for an end of file condition. Instead try this:

//Test the return condition of the file extraction, much better than eof()
while(in_stream.get(next_symbol))
{
     //do stuff
}

//Read the file safely without ever going out of bounds
while(getline(in_stream, data))
{
     //do amazing things
}

This might require some minor restructuring of your code, but this is the safe and preferred method for reading a file without having to test eof().

Edited 7 Years Ago by Clinton Portis: more cowbell.

Mainly because I have too much free time, I was just thinking about why there wasn't a c++ standard function developed that would just load your entire file all at once.. so we don't have to deal with these issues.

[Edit] I guess it already exists
http://www.cplusplus.com/reference/iostream/istream/read/

I'll definitely keep this in mind and recommend it whenever possible, if nothing else to avoid eof() issues.

Edited 7 Years Ago by Clinton Portis: infile.getfile(buffer, size); ???

As soon as you said this:


I immediately looked for this:

while (! in_stream.eof());

This is a very common problem when testing eof() for an end of file condition. Instead try this:

//Test the return condition of the file extraction, much better than eof()
while(in_stream.get(next_symbol))
{
     //do stuff
}

//Read the file safely without ever going out of bounds
while(getline(in_stream, data))
{
     //do amazing things
}

This might require some minor restructuring of your code, but this is the safe and preferred method for reading a file without having to test eof().

I'm still confused as to how you would end the loops. What condition would i test for? Would there be an outer loop with the two you mentioned nested inside? If so, how would you end the outer loop without testing for end of file? Thanks for taking the time to help.

When input methods like getline() or >> fail the return value equates to false which then prevents the loop from proceeding. Finding the end of file (EOF) is one of the conditions that causes the streams to go into a failed state, so the input will stop. (Note: If you want to use the same stream over again after a loop like this you have to resolve the failed state, if it's in one, first.) To know whether the loop has failed because the input method found EOF or whether it failed for some other reason you can test using eof(). If eof() returns true, that means EOF was found. That means that the entire file was successfully read in. If eof() returns false, then the file reading was incomplete because the stream went into a failed state for some reason other than finding EOF, though we can't say why using this test only.

This article has been dead for over six months. Start a new discussion instead.