Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Monday, December 21, 2015

How is

How is "std::cin>>value" evaluated in a while loop?


Currently I'm self-learning C++ Primer 5th. Here comes something I'm not sure. (I couldn't find the exact relevant question on F.A.Q).

Consider this while loop:

while(std::cin>>value){...}  \\value here was defined as int.   

The text book says:

That expression reads the next number from the standard input and stores that number in value. The input operator ( 1.2, p. 8) returns its left operand, which in this case is std::cin. This condition, therefore, tests std::cin.When we use an istream as a condition, the effect is to test the state of the stream. If the stream is valid?that is, if the stream hasn?t encountered an error?then the test succeeds.

My question is: does std::cin read input into value first then test the validation of std::cin, or test std::cin first then decide whether to read into 'value'? I'm quite confused about when it "returns its left operand".

Answer by Vlad from Moscow for How is "std::cin>>value" evaluated in a while loop?


There are two tests.

The first test is the condition of the while statement

while(std::cin>>value){...}  

This condition tests the result of calling operator function operator >>

The second test is a condition within the operator. If the state of the stream std::cin is good then the function tries to read an integer from the string. Otherwise it returns std::cin with the current erroneous state of std::cin.

In the while condition there is an expression

std::cin>>value  

This expression must be evaluated. So this condition tests the result of the call of operator >> .

The result of the operator is the stream std::cin But it can be contextually converted to a bool value due to operator

explicit operator bool() const;  

which returns the state of the stream

!fail().  

Answer by JSF for How is "std::cin>>value" evaluated in a while loop?


The operator first reads the value and then returns a reference to the object. The while statement first calls that operator and second tests the returned value.

Answer by Holt for How is "std::cin>>value" evaluated in a while loop?


Remember that your code is equivalent to:

while (std::cin.operator>>(value)) { }  

Or:

while (1) {      std::cin >> value ;      if (!std::cin) break ;  }  

The "code" always tries to read from std::cin into value before testing std::cin.

Let's look at the quote:

[...] The input operator ( 1.2, p. 8) returns its left operand, which in this case is std::cin. [...]

This only means that std::cin.operator>>(value) return std::cin.

This condition, therefore, tests std::cin. When we use an istream as a condition, the effect is to test the state of the stream. If the stream is valid?that is, if the stream hasn?t encountered an error?then the test succeeds.

What the text book says is that after trying to read an integer from std::cin to value, the >> operator returns std::cin. If std::cin is in a good state after reading value, then the test passes, otherwize it fails.


Some extra details:

When you do std::cin >> value, you basically call istream::operator>>(int&), and yes there is a test inside that method: If the test passes, then the internal state of std::cin is set to ios_base::goodbit, if it fails, internal state is set to on of the error flag (eofbit, failbit or badbit).

Depending on the exception mask for std::cin, if the internal test fails, an exception may be thrown.

From your quote:

When we use an istream as a condition, the effect is to test the state of the stream.

This basically mean that:

if (std::cin) { }  

Is equivalent to:

if (!std::cin.fail()) { }  

And std::cin.fail() check for failbit or badbit. This means that while (std::cin >> value) { } does not test the eofbit flag and will only fail when the input cannot be converted to an integer value.

Answer by black for How is "std::cin>>value" evaluated in a while loop?


does std::cin read input into value first then test the validation of std::cin, or test std::cin first then decide whether to read into 'value'

cin first tries to read an int from the standard input, if cin is in a good state: if it fails to, it will set the stream to a bad state; regardless of the operation done, it will return the stream itself (i.e. the "left operand" -- cin), that will allow you to check for success or failure.

If you wanted to explicitly test the validity of the stream first and only then try to read the value, you would have:

while (cin && cin >> value)  

but it's pretty redundant, since, as I've told you, cin will not even try to read value if it's already in a bad state.

Answer by mementum for How is "std::cin>>value" evaluated in a while loop?


I assume your "value" is for example an int

  • The stream tries to read input until the next whitespace.

  • if eof is found ... -> then the state will be set to "eof", >> will return the stream and the boolean evaluation of the stream will return false

  • if an error (I/O for example) happens during the reading process, the state will be set to "bad", >> will return the stream and the boolean evaluation of the stream will return false

  • if whitespace has been found, then a conversion from the read characters to int (the above assumption) will be attempted. If it fails (because the read input is for example: "xx" and not a number) the state of the stream will be set to "fail". >> will return the stream and the boolean evaluation of the stream will return false

  • if we are so far down the chain, eof was not found, no IO error (or other) happened, and the characters -> int conversion was successful. >> will return the stream and the boolean evaluation of the stream will return true.

    And your "value" will contain the appropriate value

Answer by David Hammen for How is "std::cin>>value" evaluated in a while loop?


Presumably you wouldn't have any confusion with a simple function call:

SomeReturnType some_function(int&);  while (some_function(value)) { ... }  

The above code will repeatedly call some_function until the return value from the function call, interpreted as a boolean, is false. The function is called for each step in the loop. Whether the function changes the value of value is up to the function. It certainly can do so, and presumably will do so (but that's an issue for the designer of the function).

The loop while (std::cin>>value) {...} is completely equivalent to while (std::cin.operator>>(value)) {...}. This is just a function call to the member function std::stream::operator>>(int&).


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.