How to detect the end of a file reading in a while loop in C++

Asked

Viewed 134 times

0

In my code, there’s the struct:

struct material {
    int idmaterial;
    double rho;
    double precokg;
};

And the reading function of a data vector of type "material", from a file:

std::vector<material> le_material(std::string s)
{
    std::ifstream dados(s);
    dados.exceptions(std::ios::failbit |
            std::ios::badbit);

    std::vector<material> infomateriais;
    material mat_lido;
    bool fim;
    fim = dados.eof();

    while (fim == false) {
        dados >> mat_lido.idmaterial;
        dados >> mat_lido.rho;
        dados >> mat_lido.precokg;
        infomateriais.push_back(mat_lido);
        fim = dados.eof();
    }

    return infomateriais;
}

The file being read contains the following data:

1   1.02    82.76   
2   2.81    29.45   
3   1.46    14.41   
4   1.15    31.54   
5   1.04    71.10   
6   1.11    87.05   
7   2.84    13.81   
8   1.56    27.55   
9   2.63    71.30   
10  0.87    25.59   
11  2.99    24.83   

I think the reading of the data is ok. However, the program gives error in execution when it reaches the end of the file:

terminate called after Throwing an instance of 'Std::ios_base::Failure[Abi:cxx11]' what(): basic_ios::clear: iostream error Aborted (saved kernel image)

At first, I discovered it’s because the function eof() actually only returns true when a read attempt is made that reaches the end of the file, so the program would still try to read.

Some doubts:

  • Is there any way to use the eof() without trying to make a reading and error in program execution?
  • I tried to use in the condition of while the operator >> by checking whether there was success in reading and continued to give error, because by I researched, he would try to read the final blank and not detect which is the end of the file. So, it would be better to use the get()? Like this use could be made?
  • Probably the reading is stopping in the spaces. Try reading in one command: dados >> mat_lido.idmaterial >> mat_lido.rho >> mat_lido.precokg;

  • Keep giving the same. He does the reading 11 times (as expected), but coming at the end gives the error I put in my question. How I detect the end of the file if I use the command you suggested me?

  • The text file ends exactly after the 3 of the number 24.83? If there is, for example, a new line (ENTER) or any other character after the 3, he’ll make a mistake

  • No. There’s a sort of tabulation or spacing right after the number. Only I have to read this file anyway, there’s no way to do it if it doesn’t end at the last number?

  • There are several ways :) But if you don’t have this character it is much easier. A suggestion would be to change the reading to text with getline and separate the numbers, for example, with stoi and stod

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.