EOF() function is re-reading a line of data
I have to write a program to calculate the least squares line from a set of data. I named the file "data.txt" and these are the contents:
Code:
-0.9 -1.1
-0.01 0.23
1.1 1.3
2.0 2.0
-2.0 -1.85
and this is my program so far:
Code:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
using std::ifstream;
using std::ofstream;
int main()
{
int numpoints = 0;
double x=0, y=0, sumx=0, avgx=0, sumy=0, avgy=0, sumxy=0, sumxsquared=0, sumysquared=0;
double m=0, b=0, r=0, first=0,second=0,third=0,fourth=0;
char next;
ifstream inStream;
inStream.open("data.txt");
if (inStream.fail())
{
cout << "There was an error opening the file.\n";
return 0;
}
while (! inStream.eof())
{
inStream >> x >> y;
sumx += x;
sumy += y;
sumxy += (x*y);
sumxsquared += (x*x);
sumysquared += (y*y);
numpoints ++;
inStream.get(next);
}
inStream.close();
cout << "Sum X=" << sumx <<"\n"
<< "Sum Y=" << sumy <<"\n"
<< "Sum XY=" << sumxy <<"\n"
<< "Sum X^2=" << sumxsquared <<"\n"
<< "Sum Y^2=" << sumysquared <<"\n"
<< "Number of points=" << numpoints << "\n";
return 0;
}
I havent calculated the line yet, I am stuck with reading the data from the file. From what I've read, I gathered that eof() doesn't become true until it reads past the end of the file. I read that you should use the get() function to force the program into reading the next line, triggering the eof to switch, but no matter which was I organize my while loop, I can't get it to run properly. I end up with 6 data points instead of five, the extra data point is the last data point which is re-entered into the algebra, giving me incorrect data.
Re: EOF() function is re-reading a line of data
As you say, the problem with eof is that of not neccessarilly trigered until you have read past the end of a file. In particular, it can create problems with files with new lines at the end, eg:
Code:
-0.9 -1.1\n
-0.01 0.23\n
1.1 1.3\n
2.0 2.0\n
-2.0 -1.85\n
EOF
vs
Code:
-0.9 -1.1
-0.01 0.23
1.1 1.3
2.0 2.0
-2.0 -1.85EOF
In the first case, the file has been read, up to, but not including, EOF.
The usually accepted solution to this problem is rather than scan for eof, just read your input as you normally would, until it fails. then, you check you are indeed and eof.
Code:
#include <sstream>
#include <iostream>
#include <string>
#include <cstdlib>
const std::string my_string_file1 =
"-0.9 -1.1\n"
"-0.01 0.23\n"
"1.1 1.3\n"
"2.0 2.0\n"
"-2.0 -1.85";
const std::string my_string_file2 =
"-0.9 -1.1\n"
"-0.01 0.23\n"
"1.1 1.3\n"
"2.0 2.0\n"
"-2.0 -1.85\n"
""; //newline
const std::string my_string_file3 =
"-0.9 -1.1\n"
"-0.01 0.23\n"
"1.1 1.3\n"
"2.0 2.0\n"
"-2.0 -1.85\n"
"Bad data";
int main()
{
std::istringstream my_stream(my_string_file1);
if (!my_stream)
{
std::cout << "There was an error opening the file.\n";
return EXIT_FAILURE;
}
//Read stuff here
{
double x;
double y;
while( my_stream >> x >> y )
{
//if we are here, then the read succeeded
std::cout << "I just read: " << x << " and " << y << std::endl;
}
}
if(!my_stream.eof())
{
std::cout << "An error occured while reading the file.\n";
return EXIT_FAILURE;
}
std::cout << "Done reading file." << std::endl;
return EXIT_SUCCESS;
}
You can also read Parashift's input/output FAQ.