这个程序是如何工作的

时间:2011-10-25 16:46:16

标签: c++

这是我的第一个C ++程序。它打印输入中的单词数。

我的第一个问题是,它如何进入循环并添加到计数中?是每次我输入空格字符吗?如果是这样,它怎么知道我在试图计算单词?

using namespace std;

int main() {
    int count;
    string s;
    count = 0;
    while (cin >> s)
        count++;
    cout << count << '\n';
    return 0;
}

我的第二个问题。有人可以向我解释一下命名空间std对于一个初学者意味着什么吗?

3 个答案:

答案 0 :(得分:7)

当你做cin&gt;&gt;串。你会读一个单词并把它放在字符串中。是的,它将通过char读取char,直到达到分隔符。

标准是指标准。标准C ++库位于std命名空间内。您可以在没有 using namespace std 的情况下重写或编码:

int main() {
    int count;
    std::string s;
    count = 0;
    while (std::cin >> s)
        count++;
    std::cout << count << '\n';
    return 0;
}

我不鼓励新手使用 using namespace std 语句,因为很难理解发生了什么。

答案 1 :(得分:2)

在您的代码中,cin >> s尝试从输入流中读取std::string。如果尝试成功,则返回的值cin >> s隐式转换为true,while循环继续,递增计数器。否则,while循环在尝试失败时退出,因为没有更多数据要从输入流中读取。

您可以使用std::distance来计算单词,如下所示:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>

int main() {
        std::istream_iterator<std::string> begin(std::cin), end;
        size_t count = std::distance(begin, end);
        std::cout << count << std::endl;        
        return 0;
}

演示:http://www.ideone.com/Hldz3

在此代码中,您将创建两个迭代器beginend,并将两者都传递给std::distance函数。该函数计算beginend之间的距离。距离只是输入流中字符串的数量,因为迭代器begin迭代来自输入流的字符串,end定义迭代器的结尾begin停止迭代。 begin遍历字符串的原因是std::istream_iterator的模板参数为std::string

 std::istream_iterator<std::string> begin(std::cin), end;
                     //^^^^^^^^^^^

如果将其更改为char,则begin将通过char进行迭代,这意味着以下程序将计算输入流中的字符数:

#include <iostream>
#include <algorithm>
#include <iterator>

int main() {
        std::istream_iterator<char> begin(std::cin), end;
        size_t count = std::distance(begin, end);
        std::cout << count << std::endl;        
        return 0;
}

演示:http://www.ideone.com/NH52y

同样,如果您开始使用<iterator>标头中的迭代器和<algorithm>标头中的泛型函数,您可以做很多很酷的事情。

例如,假设我们要计算输入流中的行数。那么我们将对上述计划做出哪些改变来完成工作?当我们想要计算字符数时,我们将std::string更改为char的方式立即建议现在我们需要将其更改为line,以便我们可以迭代line(而不是char line)。

由于标准库中不存在#include <iostream> #include <algorithm> #include <iterator> #include <string> struct line {}; //Interesting part! std::istream& operator >>(std::istream & in, line &) { std::string s; return std::getline(in, s); } int main() { std::istream_iterator<line> begin(std::cin), end; size_t count = std::distance(begin, end); std::cout << count << std::endl; return 0; } 类,我们自己定义一个,但有趣的是我们可以将它保持为空,如下所示,完全正常工作代码:

line

是的,与operator>>一起,您还要为line定义std::istream_terator<line>。它由{{1}}类使用。

演示:http://www.ideone.com/iKPA6

答案 2 :(得分:2)

  1. Cin将捕获输入直到空格,是的。您拥有的特定循环样式将一直持续到找到文件结束(EOF)或提供错误输入。那个循环对我来说看起来不像普通的C ++实践,但它描述了here
  2. 2. namespace std是告诉编译器在哪里查找您在代码中引用的对象的方法。因为不同的对象在不同的​​名称空间“内部”,所以你必须告诉编译器它们的具体位置(也就是std :: cin),或者告诉它为了方便你将来使用的对象(using namespace std )。