开发者

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 }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜