【问题标题】:Why will cin split a floating value into two parts?为什么 cin 会将一个浮点值分成两部分?
【发布时间】:2012-10-22 19:51:15
【问题描述】:

我对 cin 有疑问。

int main(void)
{
    int a;
    float b;
    cin >> a >> b;
}

当我给出一个浮点数(例如 3.14)作为输入时,ab 都没有得到完整的值 (3.14):输出是 a=3,b=0.14。

我知道cin 会按空格、制表符或回车分隔输入,但“点”不会,对吧?

为什么下面的代码会起作用?

int main(void)
{
    int i=0;
    int k=0;
    float j=0;

    cin >> i >> k >> j;    // i =3, j=k=0
}

还有一个问题,编译器这样做对我们有什么好处?

谢谢!

【问题讨论】:

  • '.'不能是 int 的一部分,因此格式化的 iosteam 提取停止在那里解析。至于剩下的问题,我不知道你在问什么。 cplusplus.com/reference/iostream/istream/operator%3E%3E
  • 一旦命中该点,除非您在其中添加更多代码,否则它将不会进行未来读取。

标签: c++ iostream


【解决方案1】:

您已将a 声明为int 类型,在这种情况下,您希望它与“.”做什么?

failbit 获得的输入无法解释为 合适的类型。请注意,一些 eofbit 案例也会设置 失败位。

你提到的另一个问题很好,你问的是什么问题?你已经cined 3 个变量你在这里期望什么? 0 对 float 或 int 有效。

【讨论】:

    【解决方案2】:
    cin >> a >> b;
    

    给定输入 3.14,第一次解析点(句点),因为点不适合整数的语法。第二个解析以 .14 开始,解析得很好。

    cin >> i >> k >> j;
    

    这对于输入 3.14 是有问题的。第一次解析再次停在该点上。第二次解析不能用点重新开始,所以它将输入流标记为失败。

    在执行 I/O 时始终检查状态。

    【讨论】:

      【解决方案3】:

      格式化输入函数的工作非常简单:

      1. 如果有的话,它们会跳过前导空格。
      2. 他们尝试读取与给定类型匹配的格式。
      3. 如果由于数据与所需格式不匹配而导致读取值失败,则设置为std::ios_base::failbit。如果读取失败,则输入不应更改尝试读取的变量(标准输入运算符遵循此规则,但用户定义的输入运算符可能不会)。

      您尝试读取的第一个值是int。读取int 意味着读取可选的前导符号后跟一系列数字(其中,根据您的设置和给定的值,流可能读取八进制或十六进制数字而不是十进制数字)。也就是说,int 接收到值3 并且读取在. 前面停止。

      根据您接下来阅读的内容,下一次阅读是否失败:

      • 在第一个代码中,您尝试读取以可选符号开头的浮点值,然后是可选的整数部分,然后是可选的千位分隔符,然后是可选的小数部分,然后是可选的指数。整数部分或小数部分至少需要一位数字。在您的示例中,只有数千个单独的后跟小数部分。
      • 尝试读取整数时,发现. 不是int 的有效部分,读取失败。

      在尝试读取值后,您应该始终尝试读取操作是否成功并报告潜在错误:

      if (in >> value) {
          std::cout << "successfully read '" << value << "'\n";
      }
      else {
          std::cerr << "failed to read a value from input\n";
      }
      

      请注意,在读取失败后,您可能还需要清理,例如,使用

      in.clear();
      in.ignore();
      

      这首先清除错误标志(没有这个,流将忽略任何进一步读取数据的尝试),然后忽略下一个字符。

      【讨论】:

        【解决方案4】:

        cin 正在读取输入“3.14”,您要求将其放入一个整数,然后放入一个浮点数。

        所以cin 开始阅读,找到“3”,然后找到“.”这不是整数。将 3 存储到 a 并继续。 ".14" 是有效的浮点数,它把它放入 b。

        然后你要求阅读intintfloat。第二个整数不匹配,cin 停止,但它只是似乎在工作。实际上,它失败了

        编译器无法警告您正在执行的操作不起作用,因为在编译时输入是未知的。

        【讨论】:

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