-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
  • 5,902
  • 3
  • 34
  • 60
Adam
  • 1
  • 2

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,284
  • 2
  • 8
  • 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,058
  • 1
  • 35
  • 85
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
  • 151
  • 1
  • 14