Problem reading char from file

The code reads the last character twice. I don't know where is the problem!!
here is the code:
int main()
{
ifstream startSeqF;
char ID;
startSeqF.open("starting_sequenceCHAR.txt");
if (!startSeqF.is_open())
{
cerr <<"Unable to open starting sequence input file."<<endl;
cerr <<"Test failed."<<endl;
return -1;
}
while(!startSeqF.eof()){//tried(startSeqF.good())and it doesn't work either
startSeqF >> ID;
cout<<ID<<endl;
}

startSeqF.close();
return 0;
}
input file "starting_sequenceCHAR.txt":
L
A
B
F
E
output:
L
A
B
F
E
E

the last character is always present twice...but if I change the data type of ID to string, it works...
Guys please help me!!
(Sorry for my english)
Last edited on
Don't loop on eof(). Tell the author of the book or guide you're reading to not loop on eof(). Help spread awareness of the dangers of eof() to your local community.

The problem is, eof() still returns false after you've read the last token in your file, but before the file's actual end is reached. So it enters the loop, but the last startSeqF >> ID; line fails.

Change

1
2
3
4
while(!startSeqF.eof()){//tried(startSeqF.good())and it doesn't work either
startSeqF >> ID;
cout<<ID<<endl;
}


to

1
2
3
while(startSeqF >> ID) { // in English, "while (we can successfully extract a token)"
  cout<<ID<<endl;
}
Last edited on
Thank you!!!! you have been super helpful!
Do you mind explain to me why eof() does that when ID is char? Because when ID is string type, it works...
EDIT: I went to read the eof() reference, it states that the value returned by this function depends on the last operation performed on the stream (and not on the next), so this may be the reason why it does that, but still doesn't explain why it doesn't give the same problem when ID is a string...
Last edited on
To read in a character, the file stream simply needs read in a single character, and nothing past that. That sounds pretty tautological, but the difference is that when you are reading in a string, the parser needs to keep going until it reaches something that it detects isn't part of the string. So reaching the string requires reading the EOF marker, while reading in a single character doesn't.

Just don't use eof(), even if it works some times. It won't work in a generalized case. The real issue is that you should be checking the validity of every read, so if you read in more than one piece of information after checking for eof, it makes the check for eof practically useless.

Let's say the file looks like this
 1
 2 
 3 

 1 
 2 


and you do this

1
2
3
4
5
6
7
8
9
10
11
int a;
int b;
int c;
while (!file.eof())
{
    file >> a;
    file >> b;
    file >> c;
    cout << a << b << c << endl;
    // ...
}

Your third read is still going to fail. But you won't know that something failed until you reach the top of the while loop. Better to do:
1
2
3
4
5
6
while (file >> a >> b >> c)
{
    // we know that a, b, and c were successfully read in.
    cout << a << b << c << endl;
    // ...
}
Last edited on
Topic archived. No new replies allowed.