简体   繁体   English

如何使 cin >> 不将浮点数转换为整数?

[英]How to make cin >> not convert float to integer?

I have the following simple code:我有以下简单的代码:

#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;
}

When I run the above code and input: 1.5 , it outputs: a is 1 .当我运行上面的代码并输入: 1.5 ,它输出: a is 1 FYI: I compile and run the code with gcc 4.5.3.仅供参考:我使用 gcc 4.5.3 编译并运行代码。

This means that if cin expects an integer but sees a float, it will do the conversion implicitly.这意味着如果cin需要一个整数但看到一个浮点数,它将隐式地进行转换。 So does this mean that when cin sees a float number, it is not in fail() state?那么这是否意味着当cin看到一个浮点数时,它不处于fail()状态? Why this is the case?为什么会这样? Is it because C++ does implicit conversion on >> operator?是不是因为 C++ 对>>运算符进行了隐式转换?

I also tried the following code to decide whether a given input number is integer following idea from this post: testing if given number is integer :我还尝试了以下代码来确定给定的输入数字是否为整数,遵循这篇文章的想法: 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;
}

This block of code was also not able to test whether a is integer since it simply skip the if block when I run it with float input.该代码块也无法测试a是否为整数,因为当我使用浮点输入运行它时,它只是跳过了if块。

So why this is the case when getting user input with cin?那么为什么在使用 cin 获取用户输入时会出现这种情况呢? What if sometimes I want the input to be 189 , but typed 18.9 by accident, it will result in 18 in this case, which is bad.如果有时我希望输入为189 ,但不小心输入了18.9 ,在这种情况下会导致18 ,这是不好的。 So does this mean using cin to get user input integers is not a good idea?那么这是否意味着使用cin来获取用户输入的整数不是一个好主意?

thank you.谢谢你。

When you read an integer and you give it an input of 1.5, what it sees is the integer 1, and it stops at the period since that isn't part of the integer.当你读取一个整数并给它输入 1.5 时,它看到的是整数 1,它在句点处停止,因为它不是整数的一部分。 The ".5" is still in the input. “.5”仍在输入中。 This is the reason that you only get the integer part and it is also the reason why it doesn't seem to wait for input the second time.这就是你只得到整数部分的原因,这也是它似乎没有第二次等待输入的原因。

To get around this, you could read a float instead of an integer so it reads the whole value, or you could check to see if there is anything else remaining on the line after reading the integer.为了解决这个问题,您可以读取浮点数而不是整数,以便它读取整个值,或者您可以在读取整数后检查行上是否还有其他内容。

When reading user input I prefer not to use operator>> as user input is usally line based and prone to errors.在阅读用户输入时,我不喜欢使用operator>>因为用户输入通常是基于行的并且容易出错。 I find it best to read a line at a time and validate:我发现最好一次读取一行并验证:

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

This also makes it easy to check for different types of numbers.这也使检查不同类型的数字变得容易。

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

Of course boost already supports this:当然 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 of course will convert floats as well. Boost 当然也会转换浮点数。

I have some snippet which is kind a poor coding, but it works.我有一些代码片段很糟糕,但它有效。 This method is pretty simple, but doesn't handle case when input value is invalid.这个方法很简单,但不处理输入值无效的情况。 See more: https://en.cppreference.com/w/cpp/string/byte/atof查看更多: 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM