c++ reading undefined number of lines with eof()

2019-06-14 09:26发布

问题:

I'm dealing with a problem using eof(). using

string name;
int number, n=0;
while(!in.eof())
{
    in >> name >> number;
    //part of code that puts into object array
    n++;
}

sounds normal to me as it whenever there are no more text in the file. But what I get is n being 4200317. When I view the array entries, I see the first ones ats the ones in the file and other being 0s.

What could be the problem and how should I solve it? Maybe there's an alternative to this reading problem (having undefined number of lines)

回答1:

The correct way:

string name;
int    number;
int    n     = 0;

while(in >> name >> number)
{
    // The loop will only be entered if the name and number are correctly
    // read from the input stream. If either fail then the state of the
    // stream is set to bad and then the while loop will not be entered.

    // This works because the result of the >> operator is the std::istream
    // When an istream is used in a boolean context its is converted into
    // a type that can be used in a boolean context using the isgood() to
    // check its state. If the state is good it will be converted to an objet
    // that can be considered to be true.


    //part of code that puts into object array
    n++;
}

Why your code fails:

string name;
int number, n=0;
while(!in.eof())
{
    // If you are on the last line of the file.
    // This will read the last line. BUT it will not read past
    // the end of file. So it will read the last line leaving no
    // more data but it will NOT set the EOF flag.

    // Thus it will reenter the loop one last time
    // This last time it will fail to read any data and set the EOF flag
    // But you are now in the loop so it will still processes all the
    // commands that happen after this. 
    in >> name >> number;

    // To prevent anything bad.
    // You must check the state of the stream after using it:
    if (!in)
    {
       break;   // or fix as appropriate.
    }

    // Only do work if the read worked correctly.
    n++;
}


回答2:

in << name << number;

This looks like writing, not reading. Am I wrong?



回答3:

int number, n = 0;

You weren't initializing n, and you seem to have a typo.



回答4:

This probably would be more correct

string name;
int number, n = 0;

while (in >> name && in >> number)
{
    n++;
}

The eof is a bad practice.

Note that there is a subtle difference here from your code: your code ended when it encountered an eof or silently looped for infinite time if it found a wrong line (Hello World for example), this code ends when it encounters a non correctly formatted "tuple" of name + number or the file ends (or there are other errors, like disconnecting the disk during the operation :-) ). If you want to check if the file was read correctly, after the while you can check if in.eof() is true. If it's true, then all the file was read correctly.



标签: c++ eof