Thursday, 10 May 2018

c++ - ifstream not reading EOF character



I am creating a program (In C++) that takes an ASCII file and reads a few values from each line until it reaches the end of the file. I am using ifstream to read the file, and I have never had problems with it stopping when I use the ifstream.eof() method. This time, however, even though it found the eof character in my test case, when I analyzed my other files, it is infinite looping because it never finds the eof character. Is this a coding issue, or an issue with my files?



string line = "";
unsigned long pos = 0;
ifstream curfile(input.c_str());
getline(curfile, line);
int linenumber = 0;

cout<<"About to try to read the file"<if (!curfile.good())
cout<<"Bad file read"<while (!curfile.eof())
{

cout<<"Getting line "< linenumber++;
pos = line.find_first_of(' ');
line = line.substr(pos+1, line.size()-1);

pos = line.find_first_of(' ');
current.push_back(atof(line.substr(0, pos).c_str()));
for (int i = 0; i<4; i++)
{
pos = line.find_first_of(' ');
line = line.substr(pos+1, line.size()-1);
}
pos = line.find_first_of(' ');
dx.push_back(atof(line.substr(0, pos).c_str()));
pos = line.find_first_of(' ');

line = line.substr(pos+1, line.size()-1);
pos = line.find_first_of(' ');
dy.push_back(atof(line.substr(0, pos).c_str()));
getline(curfile, line);
}


EDIT: When I first run the loop, currentfile.good() returns false...what am I doing that causes it to return that?


Answer



First thing is first, you shouldn't check like that. eof() doesn't return true until after a failed read. But you can do better (and easier)!




check the stream state with the implicit conversion to void* which can be used in a bool context. Since most of the read operations on streams return a reference to the stream, you can write some very consice code like this:



std::string line;
while(std::getline(currentfile, line)) {
// process line
}


Basically what it is doing is saying "while I could successfully extract a line from currentfile, do the following", which is what you really meant to say anyway ;-);




Like I said, this applies to most stream operations, so you can do things like this:



int x;
std::string y;
if(std::cin >> x >> y) {
// successfully read an integer and a string from cin!
}



EDIT: The way I would rewrite your code is like this:



string line;
unsigned long pos = 0;
int linenumber = 0;

ifstream curfile(input.c_str());

std::cout << "About to try to read the file" << std::endl;
while (std::getline(curfile, line)) {


std::cout << "Getting line " << linenumber << std::endl;
linenumber++;

// do the rest of the work with line
}

No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...