-1

I have this simple input data file:

1 2  
2 3

I'm reading it using the following program:

#include<cassert>
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

int main()
{
    double y[10];   
    double z[10]; 
    std::ifstream read_file("input.dat");
    assert (read_file.is_open());    

    int i=0;
    while(!read_file.eof())
    {
        read_file >> y[i] >> z[i];
        std::cout<<"y["<<i<<"]  = " << y[i] << "  z["<<i<<"]  = " << z[i]<<"\n";
        i++; 
    }
    read_file.close();
    return 0;
} 

after executing the code, I got the following output:

y[0]  = 1  z[0]  = 2
y[1]  = 2  z[1]  = 3
y[2]  = -1.6995e-41  z[2]  = 1.52064e-314  

So, the issue here that it reads an additional row of data that does not actually exist in the input file. Note that the problem is not related to the above declared array sizes y[10], z[10] ... I know that the problem is solved if I use a for loop instead. The advantage of this while loop is that it does not need to know the exact number of lines present in the input file; still I need to declare the array y and z sizes to be larger than the actual number of lines.

Any hint to get rid of the last-unwanted-line-of-data?

Please stick to the while(!read_file.eof()) form.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
Adam
  • 1
  • 2
  • 7
    Possible duplicate of [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Algirdas Preidžius Apr 13 '18 at 12:04
  • 2
    what if there are more than 10 entries in the file? Take a look at `std::vector` – 463035818_is_not_an_ai Apr 13 '18 at 12:05
  • Perhaps at the end of your file you have a character \r\n or \n. Try to remove that – Ratah Apr 13 '18 at 12:07
  • 2
    @Ratah Please read the duplicate suggestion: If one removed that, one would still have the same problem. It is caused by the fact, that `eof` flag is only set after you tried reading **past** the end of file. – Algirdas Preidžius Apr 13 '18 at 12:09
  • 3
    _"Please stick to the -- while(!read_file.eof()) -- form."_ But why? It's wrong. – underscore_d Apr 13 '18 at 12:16

3 Answers3

1

Hi just change the while loop line below:-

 while (read_file >> y[i] >> z[i])
 {
   //read_file >> y[i] >> z[i];
   std::cout<<"y["<<i<<"]  = " << y[i] << "  z["<<i<<"]  = " << z[i]<<"\n";
   i++; 
 }

The reason why your while loop execute one more time is because this read_file.eof() statement will true only when your read_file >> y[i] >> z[i]; statement reached at the end of file. You can also verify it like below:-

 while (true)
 {
   read_file >> y[i] >> z[i];
   if(!read_file.eof())
       std::cout<<"y["<<i<<"]  = " << y[i] << "  z["<<i<<"]  = " << z[i]<<"\n";
   else
      break;
   i++; 
 }
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
0

Well, while (!read_file.eof()) is incorrect as already explained by many folks in the comment section. Since you noted that you want to stick to the while (!read_file.eof()) form, I suggest here a correct one which I think is closest to what you want:

while (read_file.peek() != std::char_traits<char>::eof())
Lingxi
  • 14,579
  • 2
  • 37
  • 93
0

It works that way because of how the ifstream's '>>' operator works. It doesn't read past the'\n' and misses the eof. Try the following.

#include "stdafx.h"
#include<cassert>
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

int main()
{
    std::ofstream write_file("input.dat", ios_base::out);
    write_file << "1 2\n 3 4";
    write_file.close();

    double y[10];
    double z[10];
    std::ifstream read_file("input.dat");
    assert(read_file.is_open());

    int i = 0;
    while (!read_file.eof())
    {
        read_file >> y[i] >> z[i];
        std::cout << "y[" << i << "]  = " << y[i] << "  z[" << i << "]  = " << z[i] << "\n";
        i++;
    }
    read_file.close();

    // Add an extra '\n'
    std::ofstream write_file2("input2.dat", ios_base::out);
    write_file2 << "1 2\n 3 4\n";
    write_file2.close();

    double y2[10];
    double z2[10];
    std::ifstream read_file2("input2.dat");
    assert(read_file2.is_open());

    int i2 = 0;
    while (!read_file2.eof())
    {
        read_file2 >> y2[i2] >> z2[i2];
        std::cout << "y[" << i2 << "]  = " << y2[i2] << "  z[" << i2 << "]  = " << z2[i2] << "\n";
        i2++;
    }
    read_file2.close();


    return 0;
}
user3341576
  • 181
  • 1
  • 2
  • 16