在预期时未检测到istream结束

时间:2010-03-10 14:29:33

标签: c++

我写了一个计算元音的函数。如果在流的末尾有一个元音,它会被计算两次。为什么呢?

#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::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);
}

1 个答案:

答案 0 :(得分:4)

因为 last 读取因数据用尽而失败,in评估为false,而不是因为 next 读取因为用完而导致失败数据。它没有“向前看”,它只知道如果先前尝试过并且无法读取,则流已完成。

所以发生以下情况:

  • 读取并处理最后一个字符
  • in的计算结果为true,因此循环重复
  • 您尝试再次阅读,但没有更多数据,因此c未被修改
  • 通过未定义(虽然不足为奇)的行为,c碰巧包含它在循环的最后一次运行中所具有的值
  • 因此,您再次处理相同的字符。

你应该写:

char c;
while (in >> c) { etc }