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

Time:05-26

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?

CodePudding user response:

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.

CodePudding user response:

For starters the first program can invoke undefined behavior

int main()
{
    int x;
    while (true)
    {
        cin >> x;

        if (!x) break;
        //...

The variable x is not initialized. So if the input

cin >> x;

is not successful because for example the user interrupted the input pressing the key combination Ctrl z in Windows then in this if statement

if (!x) break;

there will be used the uninitialized variable that results in undefined behavior.

In this condition of the while loop

while (cin >> x, x)

there is used the comma operator. So whether the expression cin >> x was successful or not is ignored because the value of the expression is discarded.

You have to write

while (cin >> x && x != 0 )

Pay attention to that as the variable x has the signed type int then it means that the user can enter a negative value and the body of the loop will get the control. As a result a redundant new line character will be outputted

cout << endl;

So it is better to declare the variable x as having an unsigned integer type as for example

unsigned int x;

CodePudding user response:

The statement while (cin >> x && x) takes advantage of the fact than cin can be converted to bool. (bool) cin returns true if cin has no errors, which for most cases means always true.

The other one, I am not sure, because I am not familiar with that comma sintax.

CodePudding user response:

First while can be read as:

  • If std::cin has no errors after cin >> x, and x != 0, then execute the while block.
  • Otherwise, exit the block.

Have a look at operator bool for streams, to understand how cin >> x is used in a logical expression.

Second while can be read as:

  • Do the cin >> x.
  • Then, if x != 0, execute the while block.
  • Otherwise, exit the block.

Have a look at comma operator for understanding the use of the , in the expression.

CodePudding user response:

You should specify rules for what input could be received. For example if you want positive integers only the you would specify if x <= 0; return error

  • Related