Why will cin split a floating value into two parts?

岁酱吖の 提交于 2019-12-31 05:18:15

问题


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:

  1. They skip leading whitespace if any.
  2. They try to read a format matching the type given.
  3. 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 an int 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 cined 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!