我正在尝试计算文件中的单词数量,我知道这个问题已经被问过了,但我已经尝试了一些我见过的实现但是我一直收到错误。
我正在阅读的文件中的行是" Super Chill"但是当我运行代码时,我得到一个计数3,其中>>第一次获得Super,然后两次获得Chill。关于这种方法,我有几个问题:
1)While(in)寻找什么?怎么知道什么时候停止?
2)为什么" Chill"使用>>?
存储两次这是代码
int countWords(std::istream& in){ // line in file is -> Super Chill
int count = 0;
std::string word;
while (in) {
in >> word;
if (word != "") {
count+= 1;
}
}
return count;
}
答案 0 :(得分:5)
while (in)
检查是否没有发生错误。这与撰写while (!in.fail())
在您致电in >> word
并获得第一个“寒意”后,while (in)
仍然为真,直到下一次致电in >> word
为止。当您再次点击in >> word
时,它会失败,因为它位于文件的末尾,并且没有向word
写入任何内容,但word
变量仍然在其中显示“Chill”时间,所以你算第二次。然后while (in)
最终在下一次迭代时失败。
调用while (in >> word) { ++count; }
有效,因为in >> word
实际上是函数in.operator>>(word)
恰好返回istream&
,而istream
有operator bool
允许您在条件中使用它而不是编写!in.fail()
的方法。我知道,有点环形交叉路口。点是,它调用in >> word
,然后检查if (in)
,如果它通过,则调用++count;
并再次迭代。与原始技术相比,即使word
失败,也会计算之前的in >> word
。
为了更清楚,可能有助于知道将原始代码的if
语句更改为if (in)
也会有效,但会有一些不好的代码。
作为最后的结论,整个函数可以写成:
int countWords(std::istream& in) {
int count = 0;
for (std::string word; in >> word; ++count) {}
return count;
}
答案 1 :(得分:1)
我知道你已经找到了解决问题的方法。您可能想考虑另一种可能性:
int countWords(std::istream& in){
return std::distance(std::istream_iterator<std::string>(in),
std::istream_iterator<std::string>());
}
这实际上并没有消除循环,但是它隐藏在std::distance
内部,在那里很难弄清楚。