以下程序来自谷歌教程,它非常简单,除非我输入一个十进制数字。
#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;
}
如果输入是int(不是-1),则输出:
Enter a number (-1 = quit): 5
You entered 5
Enter a number (-1 = quit):
如果它是非数字的:
Enter a number (-1 = quit): p
You entered a non-numeric. Exiting...
All done.
这正是它应该如何工作,但如果是十进制数:
Enter a number (-1 = quit): 5.9
You entered 5
Enter a number (-1 = quit): You entered a non-numeric. Exiting...
All done.
我知道如果你将double
或float
分配给int
,c ++的行为如何,在这种情况下,它首次输出截断的十进制数,cin
不会变成false
,但第二次迭代它甚至不接受输入。
我会理解,如果它从一开始就不接受它,或者它是否只是截断了小数并且表现得像是有一个int
作为输入,但为什么它的行为与第一个循环不同,第二个循环不同?
我知道如果你将
double
或float
分配给int
,C ++的行为如何,在这种情况下,它会输出截断的十进制数。
这实际上并不是这里发生的事情。没有为你的float
分配double
或int
值。当您尝试输入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
部分,它指出允许的字符在一个整数中,并且字符.
根本没有出现。
cin >> input_var;
这是运算符>>
的操作,此运算符返回cin。然而,当这个cin传递给条件语句如if
或while
时,istreat
的特殊函数被调用来评估true
中的false
或cin
值。此函数检查cin
是否遇到和EOR
或它是否收到它想要接收的值。记住>>
是一个过载的运算符,在你的情况下,运算符被调用一个整数值。但是,当您输入非整数值(在您的情况下为double
)时,它会检测并导致错误。
虽然,结果不能以相反的方式产生,也就是当你的input_var
是类型的两倍并且你输入一个整数时,cin
将它评估为double,但是,cin
不会截断int
变量的小数后面的数字。