end of istream not detected when expected
I wrote a function to count vowels. If there is a vowel at the end of the stream it gets counted twice. Why?
#include <iostream>
#include <string>
#include <map>
using namespace std;
void countChars(istream& in, string theChars, ostream& out) {
map<char, int> charMap;
map<char, int>::iterator mapIt;
for (string:开发者_Python百科:iterator i = theChars.begin(); i != theChars.end(); ++i) {
charMap[*i] = 0;
}
while (in) {
char c;
in >> c;
c = tolower(c);
if (charMap.count(c))
++charMap[c];
}
for (mapIt = charMap.begin(); mapIt != charMap.end(); ++mapIt) {
out << (*mapIt).first << ":" << (*mapIt).second << endl;
}
}
int main(int argc, char **argv) {
std::string s = "aeiou";
countChars(std::cin, s, std::cout);
}
Because in
evaluates as false when the last read failed due to running out of data, not because the next read would fail due to running out of data. It doesn't "look ahead", it only knows that the stream is finished if it has previously tried and failed to read.
So the following happens:
- last char is read and processed
in
evaluates as true, so the loop repeats- you try to read again, but there is no more data, so c is not modified
- by undefined (although unsurprising) behavior,
c
happens to contain the value it had in the last run of the loop - hence, you process the same char again.
You should write:
char c;
while (in >> c) { etc }
精彩评论