问题
I have a problem about cin.
int main(void)
{
int a;
float b;
cin >> a >> b;
}
When I give a floating number (such as 3.14) as input, neither a
nor b
get the complete value (3.14): the output is a=3, b=0.14.
I know that cin
will split the input by space, tab or Return, but 'dot' will not, right?
And why will the following code work?
int main(void)
{
int i=0;
int k=0;
float j=0;
cin >> i >> k >> j; // i =3, j=k=0
}
And one more problem, what benefit will compiler do this for us?
Thanks!
回答1:
The formatted input functions work quite simple:
- They skip leading whitespace if any.
- They try to read a format matching the type given.
- If reading the value fails because the data doesn't match the required format, they set
std::ios_base::failbit
. If reading fails the input shouldn't change the variable attempted to be read (the standard input operators follow this rule but user defined input operator might not).
The first value you try to read is an int
. Reading an int
means that a optional leading sign is read followed by a sequence of digits (where, depending on your settings and the value given, the stream may read octal or hexadecimal numbers rather than decimal ones). That is, the int
receives the value 3
and reading stops right in front of the .
.
Depending on what you read next, the next read fails or doesn't:
- In the first code you try to read a floating point value which starts with an optional sign, followed by an optional integral parts, followed by an optional thousands separator, followed by an optional fractional part, followed by an optional exponent. At least one digit is required in either the integral or the fractional part. In your example, there is only a thousands separate followed by a fractional part.
- When trying to read an integer, a
.
is found which isn't a valid part of anint
and reading fails.
After attempting to read a value, you should always try if the read operation was successful and report potential errors:
if (in >> value) {
std::cout << "successfully read '" << value << "'\n";
}
else {
std::cerr << "failed to read a value from input\n";
}
Note, that after a failed read you may need to clean up as well, e.g., using
in.clear();
in.ignore();
This first clears the error flags (without this, the stream would ignore any further attempts to read the data) and then it ignores the next character.
回答2:
You've declared a
to be of type int
, in which case what do you expect it to do with the "."?
failbit The input obtained could not be interpreted as an element of the appropriate type. Notice that some eofbit cases will also set failbit.
The other mention you have works fine what is the issue you are asking about? You've cin
ed 3 variables what did you expect here? 0 is valid for float or int.
回答3:
cin >> a >> b;
Given an input of 3.14, the first parse on the dot (period) because dot doesn't fit the syntax for an integer. The second parse picks up with .14, which parses just fine.
cin >> i >> k >> j;
This is problematic with an input of 3.14. The first parse once again stops on the dot. The second parse can't restart with the dot, so it marks the input stream as failed.
Always check status when doing I/O.
回答4:
cin
is reading input "3.14" and you ask to put it into an integer and then a float.
So cin
starts reading, finds "3", then finds "." which is not integer. Stores 3 into a
and continues. ".14" is valid float and it puts it into b.
Then you ask to read int
, int
, float
. The second integer is not matched and cin
stops, but it only appears to be working. Actually, it failed.
The compiler can't warn you that you're doing something which will not work, because the input is not known at compile time.
来源:https://stackoverflow.com/questions/13018742/why-will-cin-split-a-floating-value-into-two-parts