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 aftercin >> x
, andx != 0
, then execute thewhile
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 thewhile
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