为什么if(!(cin >> int))在第一次迭代中接受十进制数而不接受其他十进制数?

Zer*_*oAG 1 c++ int if-statement decimal cin

以下程序来自谷歌教程,它非常简单,除非我输入一个十进制数字.

#include <iostream>
using namespace std;

int main() {
  int input_var = 0;
  do {
    cout << "Enter a number (-1 = quit): ";

    if (!(cin >> input_var)) {
      cout << "You entered a non-numeric. Exiting..." << endl;
      break;
    }

    if (input_var != -1) {
      cout << "You entered " << input_var << endl;
    }

  } while (input_var != -1);

  cout << "All done." << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果输入是int(不是-1),则输出:

Enter a number (-1 = quit): 5
You entered 5
Enter a number (-1 = quit):
Run Code Online (Sandbox Code Playgroud)

如果它是非数字的:

Enter a number (-1 = quit): p
You entered a non-numeric. Exiting...
All done.
Run Code Online (Sandbox Code Playgroud)

这正是它应该如何工作,但如果是十进制数:

Enter a number (-1 = quit): 5.9
You entered 5
Enter a number (-1 = quit): You entered a non-numeric. Exiting...
All done.
Run Code Online (Sandbox Code Playgroud)

我知道C++的行为,如果你分配一个doublefloat一个int,在这种情况下,它输出截断十进制数首次cin没有成为false,但在第二次迭代它甚至不接受输入.

我会理解,如果它从一开始就不接受它,或者它是否只是截断了小数,并且表现得像它有一个int输入一样,但为什么它的行为与第一个循环不同,第二个循环不同?

pax*_*blo 5

我知道,如果你分配一个C++的行为double或者floatint,在这种情况下,它输出截断十进制数.

这实际上并不是这里发生的事情.没有为您分配a floatdoubleint.当您尝试输入整数时5.9,它会成功获取该5位并停在那里,留.9在输入流中.在任何阶段,您都没有5.9从输入流中提取完整内容并将其截断为整数以便放入input_var.

然后,在下一次迭代中,它发现,它.9确定它不是一个有效的整数,并且相应地起作用,就像你输入的那样p.

这在C++ 14 22.4.2.1 num_get()中有详细介绍,但是底线在该描述的第3阶段:

在阶段2(字段)中累积的字符序列将通过标头中声明的其中一个函数的规则转换为数字值<cstdlib>:

对于有符号整数值,该函数strtoll.

我不会去太多的细节的方式strtoll工作,因为它需要通过ISO C99的相当多的部分步进为好.可以说它最终出现在一个段中6.4.4 Constants,该段指出允许的字符在一个整数中,并且该字符.根本没有出现.