简体   繁体   中英

How does this program work

This is my first C++ program. It prints the number of words in the input.

My first question, how does it go into the loop and add to the count? is it every time i type the space character? if so, how does it know I'm trying to count words?

using namespace std;

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

My second question. Can someone explain to me what namespace std means for a begineer?

When you do cin >> string. You will read a word and put it in the string. Yes, it will read char by char until reach the delimiter.

Std means Standard. Standard C++ library is inside the std namespace. You can rewrite or code without the using namespace std :

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

I discourage that novices use the using namespace std statement because it is harder to understand what is going on.

In your code, cin >> s attempts to read a std::string from input stream. If the attempt succeeds, then the returned value of cin >> s implicitly converts into true and the while loop continues, incrementing the counter. Otherwise, the while loop exits when the attempt fails, as there is no more data to read from the input stream.

You can use std::distance to count the words, as shown below:

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

Demo : http://www.ideone.com/Hldz3

In this code, you create two iterators begin and end , passing both to std::distance function. The function calculates the distance between begin and end . The distance is nothing but the number of strings in the input stream, because the iterator begin iterates over strings coming from the input stream, and end defines the end of the iterator where begin stops iterating. The reason why begin iterates over strings is because the template argument to std::istream_iterator is std::string :

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

If you change this to char , then begin will iterator over char , which means the following program will count the number of characters in the input stream:

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

Demo : http://www.ideone.com/NH52y

Similarly, you can do many cool things if you start using iterators from <iterator> header and generic functions from <algorithm> header.

For example, let say we want to count the number of lines in the input stream. So what change would we make to the above program to get the job done? The way we change std::string to char when we wanted to count characters, immediately suggests that now we need to change it to line so that we could iterate over line (instead of char ).

As no line class exist in the Standard library, we've to define one ourselves, but the interesting thing is that we can keep it empty as shown below, with full working code:

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

Yes, along with line , you've to define operator>> for line as well. It is used by std::istream_terator<line> class.

Demo : http://www.ideone.com/iKPA6

  1. Cin will capture input until a space, yes. The specific style of loop you have will go until an End-Of-File (EOF) is found or until bad input is provided. That loop doesn't look like common C++ practice to me, but it's described here .

2. namespace std is how you tell the compiler where to look to find the objects you're referencing in your code. Because different objects are "inside" different namespaces, you either have to tell the compiler where they are specifically (aka std::cin) or tell it for convenience where an object you use will be in the future (with using namespace std ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM