Search code examples
c++while-loopcomma-operator

Question on while (true), while (cin >> x && x), while (cin >> x, x)


I have encountered a problem with this task:

your input is a number and the output is from 1 to the input number. If the number is zero, the output will be nothing.

For instance your input is

5
10
3
0

Your output will be

1 2 3 4 5
1 2 3 4 5 6 7 8 9 10
1 2 3

So, there are apparently three answers.

The first solution uses this:

#include <iostream>
    
using namespace std;
    
int main()
{
    int x;
    while (true)
    {
        cin >> x;
    
        if (!x) break;
    
        for (int i = 1; i <= x; i ++ ) cout << i << ' ';
        cout << endl;
    }
    
    return 0;
}

The other two solutions replace this:

while (true)
{
    cin >> x;
    
    if (!x) break;

with this:

while (cin >> x && x)

or this:

while (cin >> x, x)

I understand the first solution, but not the other two.

Can someone help me?


Solution

  • The >> operator, by convention, when applied to an istream object should return the istream object itself. So the return value of cin >> x is the cin object itself. When used as a Boolean, a stream object returns truthy if there are no errors in input/output.

    while (cin >> x && x)
    

    This says "while the loop successfully reads a value without errors and that value is not zero".

    The comma operator is one of the more obscure pieces of C++ syntax. a , b evaluates a and then b and returns the result of b, discarding the result of a (this is assuming the comma doesn't do something else; for instance, in a function argument list the comma is part of that syntax, not its own operator). So cin >> x, x says "do the cin part, ignore the return value of that, and then check x".

    while (cin >> x, x)
    

    This says "get input and run as long as the input is nonzero". Crucially, errors in the input process are ignored here.


    Minor note: Technically, programmers can overload the comma operator to call an arbitrary function. So if a programmer (whose mental health we might call into question) wrote a function like

    void operator,(const istream& in, int x) {
      // Something really stupid ...
    }
    

    Then that function would get called by cin >> x, x. But every C++ style guide I've ever seen recommends against ever overloading the comma operator, so this is pathological at best.