【问题标题】:How to make cin >> not convert float to integer?如何使 cin >> 不将浮点数转换为整数?
【发布时间】:2013-03-13 18:21:22
【问题描述】:

我有以下简单代码:

#include <iostream>
int main()
{
   int a;
   std::cout << "enter integer a" << std::endl;
   std::cin >> a ;

   if (std::cin.fail())
   {
      std::cin.clear();
      std::cout << "input is not integer, re-enter please" <<std::endl;
      std::cin >>a;
      std::cout << "a inside if is: " << a <<std::endl;
   }
   std::cout << "a is " << a <<std::endl;
   std::cin.get();
   return 0;
}

当我运行上面的代码并输入:1.5,它输出:a is 1。仅供参考:我使用 gcc 4.5.3 编译和运行代码。

这意味着如果cin 需要一个整数但看到一个浮点数,它将隐式进行转换。那么这是否意味着当cin 看到一个浮点数时,它并不处于fail() 状态?为什么会这样?是不是因为C++对&gt;&gt;操作符做了隐式转换?

我还尝试了以下代码来确定给定的输入数字是否为整数,遵循这篇文章的想法:testing if given number is integer:

#include <iostream>
bool integer(float k)
{
    if( k == (int) k) return true;
    return false;
}

int main()
{
   int a;
   std::cout << "enter integer a"<< std::endl;
   std::cin >> a ;

   if (!integer(a))
   {
     std::cout << "input is not integer, re-enter please" ;
     std::cin.clear();
     std::cin >> a;
     std::cout << "a inside if is: " << a <<std::endl;
   }
   std::cout << "a is " << a <<std::endl;
   std::cin.get();
   return 0;
}

此代码块也无法测试 a 是否为整数,因为当我使用浮点输入运行它时,它只是跳过了 if 块。

那么为什么在使用 cin 获取用户输入时会出现这种情况?如果有时我希望输入为189,但不小心输入了18.9,在这种情况下会导致18,这很糟糕。那么这是否意味着使用cin 获取用户输入整数不是一个好主意?

谢谢。

【问题讨论】:

  • 第 4 行。int a; --->双a;
  • 如果您将输入 a 作为浮点数而不是整数,然后检查 a == (int)a 是否也会告诉您它是否是整数。
  • cin“知道”它正在读取什么类型,并根据类型执行不同的操作。对于 int,它读取数字,并在看到非数字时立即停止。在您的示例中,它读取整个“1.2”,它在“1”之后停止,因为下一个字符不是数字。

标签: c++ integer cin


【解决方案1】:

当你读取一个整数并给它输入 1.5 时,它看到的是整数 1,它在句点处停止,因为它不是整数的一部分。 “.5”仍在输入中。这就是你只得到整数部分的原因,也是第二次似乎没有等待输入的原因。

要解决这个问题,您可以读取浮点数而不是整数,以便读取整个值,或者您可以在读取整数后检查行上是否还有其他内容。

【讨论】:

    【解决方案2】:

    在阅读用户输入时,我不喜欢使用operator&gt;&gt;,因为用户输入通常是基于行的并且容易出错。我发现最好一次读取一行并验证:

     std::string   line;
     std::getline(std::cin, line);
    

    这也使得检查不同类型的数字变得容易。

     std::stirngstream linestream(line);
     int  val;
     char c;
    
     if ((linestream >> val) && !(linestream >> c))
     {
         // Get in here if an integer was read.
         // And there is no following (non white space) characters.
         // i.e. If the user only types in an integer.
         // 
         // If the user typed any other character after the integer (like .5)
         // then this will fail.
    }
    

    当然 boost 已经支持这个了:

    val = boost::lexical_cast<int>(linestream); // Will throw if linestream does 
                                                // not contain an integer or
                                                // contains anything in addition
                                                // to the integer.
    

    Boost 当然也会转换浮点数。

    【讨论】:

      【解决方案3】:

      我有一些 sn-p,这是一种糟糕的编码,但它可以工作。 这个方法很简单,但是不处理输入值无效的情况。 查看更多:https://en.cppreference.com/w/cpp/string/byte/atof

      static float InputFloat(std::string label)
      {
          std::string input;
          std::cout << label;
          std::cin >> input;
          return atof(input.c_str());
      }
      
      int main()
      {
          float value = InputFloat("Enter some float value: ");
          std::cout << "value = " << value;
          return 0;
      }
      

      【讨论】:

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