【问题标题】:Why does if(!(cin >> int)) accept a decimal number in the first iteration but not the other ones?为什么 if(!(cin >> int)) 在第一次迭代中接受十进制数而不接受其他数?
【发布时间】:2017-12-24 02:18:06
【问题描述】:

以下程序来自谷歌教程,非常简单,除非我输入十进制数。

#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.

我知道如果将doublefloat 分配给int 并且在这种情况下它第一次输出截断的十进制数并且cin 不会变成false,那么c++ 的行为第二次迭代它甚至不接受输入。

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

【问题讨论】:

  • iostreams 输入的一个很好的默认值是使用getline,来自&lt;string&gt; 标头。
  • “十进制数”是什么意思?你是说base-10吗?因为这是唯一真正的意义。
  • @EJP 也表示“用小数点表示的非整数值”。这是我的问题中标签“十进制”定义的一部分。很抱歉有歧义。

标签: c++ if-statement int decimal cin


【解决方案1】:

如果您将 doublefloat 分配给 int,我知道 C++ 的行为方式,在这种情况下,它会输出截断的十进制数。

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

然后,在下一次迭代中,它找到.9,发现它不是一个有效的整数,并采取相应的行动,就像你输入p时一样。

这在 C++14 的 22.4.2.1 num_get() 部分中有详细介绍,但最重要的是该描述的第 3 阶段:

在第 2 阶段(字段)中累积的字符序列通过标头 &lt;cstdlib&gt; 中声明的函数之一的规则转换为数值:

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

我不会详细介绍strtoll 的工作方式,因为它还需要逐步了解 ISO C99 的很多部分。可以说它在6.4.4 Constants 部分结束,该部分规定了允许的整数中的字符,并且字符. 根本不出现。

【讨论】:

    【解决方案2】:
    cin >> input_var;
    

    这是运算符&gt;&gt; 的运算,此运算符返回cin。但是,当将此 cin 传递给诸如 ifwhile 之类的条件语句时,将调用 istreat 的特殊函数来评估来自 cintruefalse 值。此函数检查 cin 是否遇到和 EOR 或者它接收到它应该接收的值。请记住 &gt;&gt; 是一个重载运算符,在您的情况下,该运算符被调用为一个整数值。但是,当您输入一个非整数值(在您的情况下为double)时,它会检测到并导致错误。

    虽然,结果不能以相反的方式产生,即当您的input_var 是双精度类型并且您输入一个整数时,cin 将其计算为双精度,但是,cin 不会截断数字int 变量的小数点后。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      相关资源
      最近更新 更多