This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How would std::ostringstream convert to bool?
#include<iostream.h>
void main() {
if(cin>>2) { // what is cin>>2 doing inside arg of if
cout<<"if works";
} else {
cout<<"else works";
}
}
We don't get error in this code.But Alwaysif statement works why? how?
cin >> 2 is invalid. cin >> integervar is valid, assuming that's what you mean?
The standard library class ios which basic_istream (and thus cin) inherits from overloads operator void * (and operator!) to allow you to do such tests.
operator void * returns 0 if failbit or badbit is set - aka the last extraction failed.
This is the "standard" way of combining extraction and checking if the extraction succeeded.
if(cin>>2)
This wouldn't even compile. See this : http://ideone.com/MiEkq
What you probably mean is : if(cin>>var)
If that is so, then it means IF the read from the input stream succeeds, then then if block will be executed because after successful read, the returned std::istream & can implicitly convert into true, otherwise it converts into false.
BTW, the return type of main() should be int.
Related
This question already has answers here:
Value stored when istream read fails
(2 answers)
Closed last month.
Instead of atoi I use operator>> of stringstream in the following function in order to convert a string into an int.
int MyString::Int()
{
int f = 0;
std::stringstream ss;
ss << *this;
ss >> f;
return f;
}
Is it guarenteed that operator>> does not touch integer variable "f" if it cannot convert the string data coming from "*this" into the integer?
Or can it happen that stringstream "ss" is set to failure by operator<< and therefore operator>> makes undefined behaviour because I do not check the state of the stream?
Edit: The answer is already here:
istream behavior change in C++ upon failure
There it is described that the behaviour changed in C++11 regarding if the value is left unchanged in some circumstances or set to zero if a conversion cannot be made. In my example above however the int variable is initialised anyway and therefore the return value would always be zero independently if the stream reaches eof before or the conversion is not possible.
ss >> f; may (and likely will) initially set f to 0 before trying to extract an integer from its internal buffer.
Regardless whether the extraction is a success (because of a previously or newly encountered error), you will not invoke UB. The operation will fail due to the incorrect stream state. It's perfectly valid and you can check for such states.
Code
#include<iostream>
int main()
{
int x;
std::cout<<(std::cin>>x)<<"\n";
std::cin.clear();
std::cin.ignore();
if(std::cin>>x)
{
std::cout<<"inside the if-block\n";
}
}
Output-1
2 // input-1
0x486650
3 // input-2
inside the if-block
for input 2 cin>>x succeeds but gives 0x486650
for input 3 if-block executed means it returns 1.
Output-2
a // input-1
0
b // input-2
for input a cin>>x fails and gives 0 as expected.
for input b cin>>x if-block not executed means it returns 0
So why std::cout<<(std::cin>>x) returns something like 0x486650 when succeeds ?
Before C++11 streams didn't have an operator bool() and had an operator void*() instead, see https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool.
When used as intended i.e.:
if (std::cin)
{
}
or:
if (std::cin >> x)
{
}
There is no difference between the C++11 and pre C++11 behaviour.
However if you try to directly print a stream:
std::cout<<std::cin;
In C++11 this fails to compile as there is no standard stream operator that takes an input stream and the boolean conversion operator is marked as explicit.
In C++03 however the void* conversion is not explicit so "printing" an input stream results in the fairly surprising behaviour of printing a pointer. If the stream is in a failed state the pointer will be null so 0 will be printed. If the stream isn't in a failed state the pointer will be non-null (possibly a pointer to the stream itself, this isn't specified by the standard) so will result in a non-zero address being printed. e.g. see https://godbolt.org/z/dM3ce5Kes
This question already has answers here:
Why does stringstream >> change value of target on failure?
(2 answers)
Closed 7 years ago.
I am completely new to C++ and am trying to write an extremely basic program, but I am having issues with initializing an integer. I have stripped it down to a very small program that still has the issue:
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter your age\n";
int age = -1;
cin >> age;
cout <<"\n\n Your age is " << age << "\n\n";
}
I read that if I attempt to input a string, e.g. abc to the age variable, then the input should fail and the value should be left alone and therefore it should print Your age is -1.
However, when I run this program and type abc, then it prints Your age is 0. Why?
The behavior you want to observe changed in 2011. Until then:
If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.
But since C++11:
If extraction fails, zero is written to value and failbit is set. [...]
(From cppr.)
With the compiler I tested against (gcc 4.8.4), the value is set to zero (for the 'abc' input) regardless of which version of the standard I compile against. Note also that it is set to minimum/maximum values if you provide a valid integer that is outside of the supported range of the variable that you are assigning to.
A more important point though, is that ignoring error flags is a recipe for disaster. Once you have an error in the input, any subsequent input is suspect (without hacks like ignore()). Situations like this are a good candidate for using exception handling.
Here's how I might implement what you are trying to do (but, again, considering the case of multiple inputs, recovering from errors is a messy business):
cin.exceptions( ~std::ios::goodbit );
try { cin >> age; }
catch ( std::ios::failure const & )
{
age=-1;
cin.clear();
cin.ignore(999,'\n');
}
or without exeptions:
cin >> age;
if ( cin.fail() ) age=-1, cin.clear(), cin.ignore(999,'\n');
See here for similar questions:
Why does stringstream >> change value of target on failure?
istream behavior change in C++ upon failure
Here are up-to-date docs for the operator in question:
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt
I've used statements such as this quite a bit in my C++ programming:
std::string s;
std::ifstream in("my_input.txt");
if(!in) {
std::cerr << "File not opened" << std::endl;
exit(1);
}
while(in >> s) {
// Do something with s
}
What I want to know is, why does this work?
I looked at the return value of operator>>, and it's an istream object, not a boolean. How does an istream object somehow get interpreted as a bool value that can be put inside of if statements and while loops?
The base class std::basic_ios provides an operator bool() method that returns a boolean representing the validity of the stream. For example, if a read reached the end of file without grabbing any characters, then std::ios_base::failbit will be set in the stream. Then operator bool() will be invoked, returning !fail(), at which time extraction will stop because the condition is false.
A conditional expression represents an explicit boolean conversion, so this:
while (in >> s)
is equivalent to this
while (static_cast<bool>(in >> s))
which is equivalent to this
while ((in >> s).operator bool())
which is equivalent to
while (!(in >> s).fail())
std::basic_ios, from which the input and output streams inherit, has the conversion function operator bool (or operator void* prior to C++11 to get around the safe-bool problem, which is no longer an issue thanks to the explicit keyword).
See std::basic_ios::operator bool:
This operator makes it possible to use streams and functions that return references to streams as loop conditions, resulting in the idiomatic C++ input loops such as while(stream >> value) {...} or while(getline(stream, string)){...}. Such loops execute the loop's body only if the input operation succeeded.
Here is a C++ code which reads as many words
from a given text file as possible until it meets EOF.
string text;
fstream inputStream;
inputStream.open("filename.txt");
while (inputStream >> text)
cout << text << endl;
inputStream.close();
My question is:
what procedure exactly is performed behind on converting the condition of the while loop (i.e., inputStream >> text) into a boolean values (i.e., true or false)?
My own answer for the question is:
To my understanding, inputStream >> text is supposed to return another (file) input stream. The stream seems to be NULL when EOF arrives. The NULL may be defined as 0, which is equivalent to false.
Does my answer make sense? Even if my answer does make sense, such conversion of InputStream to bool doesn't make me so comfortable. :)
what procedure exactly is performed behind on converting the condition of the while loop (i.e., inputStream >> text) into a boolean values (i.e., true or false)?
operator>> returns a reference to the stream.
In C++11 the reference is then converted to a bool by the stream's operator bool() function, which returns the equivalent of !fail().
In C++98 the same is achieved by using operator void*(), and the returned pointer is either NULL to indicate failure or a non-null pointer if fail() is false, which is then implicitly converted to a bool in the while evaluation.
I know that my answer has been perfectly answered by user657267. But I am adding one more example to understand the answer more easily.
// evaluating a stream
#include <iostream> // std::cerr
#include <fstream> // std::ifstream
int main () {
std::ifstream is;
is.open ("test.txt");
if (is) { <===== Here, an example of converting ifstream into bool
// read file
}
else {
std::cerr << "Error opening 'test.txt'\n";
}
return 0;
}
Ref. http://www.cplusplus.com/reference/ios/ios/operator_bool/