-
problem with fstream
Hi,
I have very strange problem with std::fstream. I want to read a simple two-column space-separated file with the following code:
#include <iostream>
#include <fstream>
Code:
Code:
int main() {
std::ifstream file("file.txt");
unsigned long oldval;
unsigned long newval;
while(!file.eof()) {
file >> oldval;
file >> newval;
std::cout << oldval << " " << newval << std::endl;
}
}
The file.txt contains ten lines only:
Code:
3036679276 4677957
3233819949 6457113
3602920021 7347886
6236944672 16846074
2487223488 3069408
2818574689 4363018
5419052468 13941073
9172944933 31529903
2818574690 4363020
9172944938 31529909
As output, I get an endless printing of the 3rd line. I have tried a lot of variants, like:
Code:
while(file>>oldval>>newval)
or
while(file.good())
i also have printed the get pointer with file.tellg() and always get -1. Lastly, i tried reading one line, then created a stringstream and read from it:
Code:
int main()
{
std::ifstream file("file.txt");
unsigned long oldval;
unsigned long newval;
std::string line;
while(!file.eof()) {
std::getline(file, line);
std::stringstream linestream(line);
linestream >> oldval;
linestream >> newval;
std::cout << oldval << " " << newval << std::endl;
}
}
i get the following:
I get the following:
3036679276 4677957
3233819949 6457113
3602920021 7347886
3602920021 7347886
2487223488 3069408
2818574689 4363018
2818574689 4363018
2818574689 4363018
2818574690 4363020
2818574690 4363020
2818574690 4363020
It looks like the seek internal pointer of fstream is not moving. Any clues about this? I'm in RH with GCC3.4. ????? I don't get it :S Any ideas??? I'm starting to believe that my computer is possessed
-
> 6236944672
Probably because this doesn't fit into an unsigned long, and you're getting a conversion error.
> while(!file.eof())
This is bad, see the FAQ
Maybe
Code:
while( std::getline(file, line) ) {
std::stringstream linestream(line);
if ( linestream >> oldval >> newval ) {
std::cout << oldval << " " << newval << std::endl;
} else {
std::cout << "Bad input" << std::endl;
}
}
-
Re: Problem with fstream
Thanks a lot for your time. I changed the data type to long long and it worked.
>> while(!file.eof())
> This is bad, see the FAQ
The eof that the FAQ talks about is from C, i think that the std::fstream::eof() function solves that problems, at least in my program works fine. Do you know if this is true for C++ (that the efo() works fine)?
Thanks
-
There are similar issues with using eof() to control a loop in C++, although they are not exactly the same. If your original code was working, you would likely be outputting the last pair of values twice. Can you post your current version?
-
Hi, this is my last working version
Code:
int main() {
std::ifstream file("file.txt");
unsigned long long oldval, newval;
while(!file.eof()) {
file >> oldval >> newval;
std::cout << oldval << " " << newval << std::endl;
}
}
The values are printed only once. It seems to work fine but I don't know if there are issues with using it.
Thanks
-
Wait! You're right, my final version is not that one, is this one:
Code:
int main() {
std::ifstream file("file.txt");
unsigned long long oldval, newval;
while(!file.eof()) {
if(file >> oldval >> newval) {
std::cout << oldval << " " << newval << std::endl;
} else {
std::cout << "bad input" << std::endl;
}
}
}
with the previous version I do get the last line printed twice. With this one I get a bad input instead of the repetition of the last line. Can you explain what does this happens? Or where can we read about it? I'd really appreciate it.
Thanks for your time.
-
>> where can we read about it?
I have never seen it explained correctly, although I'm sure it is somewhere. I have explained it a couple times, but it would be hard to search for since I've posted more than a few times on here, and more than a few times on the subject. I will search for the thread or give an explanation later (tomorrow my time).
-
> while(!file.eof())
Why are you still doing this? It's been explained enough already.
feof(), whether in C or C++ is a state (of past events), not a prediction (for future actions).
The end of file state is only set by you performing some read action, namely this
if(file >> oldval >> newval)
Your bad input message at this point really means end of file, not conversion error.
Which if you made your else look like this
Code:
else {
if ( file.eof() ) {
std::cout << "EOF!!!" << std::endl;
} else {
std::cout << "bad input" << std::endl;
}
}
What is worse, is that if you actually corrupt your file, you STILL lock up because things like
file >> oldval >> newval
do NOT skip over bad input data.
Just but a line of characters in your file instead of pairs of numbers.