I wrote a program to read real numbers from a file,
program is supposed to give 5 output ,as there are 5 list of numbers but I'm getting last numbers list repeated.
#include<iostream>
#include<fstream>
#include<string>
usingnamespace std;
int main(){
// std::ios::sync_with_stdio(false); // to speed up reading
ifstream testfile;
string line;
uint_fast16_t n,i=0;
float lat1,lat2,lng1,lng2;
testfile.open("testfile.txt");
if (!testfile) {
cout << "Unable to open file";
exit(1); // terminate with error
}
testfile.seekg(19,ios::beg);//skip to last of first line
testfile>>n;
testfile.seekg(21,ios::beg);
getline(testfile,line);//read next line;
while (!testfile.eof())
{getline(testfile,line,' ');
testfile>>lat1;testfile>>lng1;testfile>>lat2;testfile>>lng2;
cout<<" "<<lat1<<" "<<lng1<<" "<<lat2<<" "<<lng2<<endl;
}
testfile.close(); // Step 5: Closing file
return 0;
}
@Sholi, I think you have made this exercise spectacularly difficult for yourself.
Your use of seekg for positioning completely crippled my system.
Your use of .eof as a test doesn't work because you don't actually reach the end of file until you try (and fail) to read another item. When the test fails at this point you have already entered the while loop, so failure to read new values leaves you with the previously read ones.
The main problem is your indentation is deceptive, but the issue you complain about is probably caused by this line: while (!testfile.eof())
The stream will enter in the EOF condition after having read the last line, therefore your loop will execute one more time. The most common solution is to check the stream status directly.
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
int main()
{
std::ifstream testfile("testfile.txt");
if (!testfile) {
std::cout << "Unable to open file.\n";
std::exit(1); // terminate with error
}
std::string line;
std::getline(testfile, line);
// Get the number of the end of first line:
line = line.substr(line.find_last_of('=') + 1);
std::istringstream iss { line };
uint_fast16_t loc_num;
iss >> loc_num;
std::cout << "There are " << loc_num << " coordinates in the file:\n";
// Get ditch of the heading line:
std::getline(testfile, line);
// Read the coordinates:
while(std::getline(testfile, line)) {
iss.clear();
iss.str(line);
double lat1, lat2, lng1, lng2;
iss >> line >> lat1 >> lat2 >> lng1 >> lng2;
std::cout << line << ':' << std::fixed << std::setprecision(7)
<< std::setw(11) << lat1
<< std::setw(11) << lng1
<< std::setw(11) << lat2
<< std::setw(11) << lng2
<< '\n';
}
// Redundant so far: the file stream will be automatically closed at the
// end of the function:
// testfile.close();
return 0;
}
@Enoizat I'm not getting why loop will run again,
when reading last line , last line gets printed,
EOF is true : so while should stop,
& even if while doesn't stops,(as u say) how are the values lat1,lat2,lng1,lng2 are getting updated with same values as their previous one?
EOF is true : so while should stop,
& even if while doesn't stops,(as u say) how are the values lat1,lat2,lng1,lng2 are getting updated with same values as their previous one?
No, EOF is NOT true at this point ... nor are lat1, lat2, lng1, lng2 getting updated. (They are simply stuck with their previous values.)
When it has read the last line of data ... it is at the end of that line of data. It does not know about EOF UNTIL IT TRIES TO READ THE NEXT PIECE OF DATA. At that point, because the while() condition is true it has to complete the loop. It fails to read any new data into the variables ... which just retain their values from the previous read, so that is what is printed out. One way to confirm that would simply be to set them to some recognisable sentinel value immediately after you cout them.
As a general principle, DON'T TEST FOR EOF ... test for the condition of the stream. As in both mine and @Enoizat's examples you can conveniently do that within the while() test. Neither of us use EOF.