【问题标题】:Checking cin input stream produces an integer检查 cin 输入流产生一个整数
【发布时间】:2013-09-14 17:50:53
【问题描述】:

我正在输入这个,它要求用户输入两个整数,然后它们将成为变量。从那里它将执行简单的操作。

如何让计算机检查输入的内容是否为整数?如果没有,请用户输入一个整数。例如:如果有人输入“a”而不是 2,那么它会告诉他们重新输入一个数字。

谢谢

 #include <iostream>
using namespace std;

int main ()
{

    int firstvariable;
    int secondvariable;
    float float1;
    float float2;

    cout << "Please enter two integers and then press Enter:" << endl;
    cin >> firstvariable;
    cin >> secondvariable;

    cout << "Time for some simple mathematical operations:\n" << endl;

    cout << "The sum:\n " << firstvariable << "+" << secondvariable 
        <<"="<< firstvariable + secondvariable << "\n " << endl;

}

【问题讨论】:

  • 检查输入操作是否失败。
  • 'a' 仍然是一个整数值。您可以检查该值是否在 ASCII 数字范围内,即 0x30-0x39

标签: c++ cin


【解决方案1】:

你可以这样检查:

int x;
cin >> x;

if (cin.fail()) {
    //Not an int.
}

此外,您可以继续获取输入,直到通过以下方式获得 int:

#include <iostream>



int main() {

    int x;
    std::cin >> x;
    while(std::cin.fail()) {
        std::cout << "Error" << std::endl;
        std::cin.clear();
        std::cin.ignore(256,'\n');
        std::cin >> x;
    }
    std::cout << x << std::endl;

    return 0;
}

编辑:要解决下面关于 10abc 等输入的评论,可以修改循环以接受字符串作为输入。然后检查字符串中是否有任何字符而不是数字并相应地处理这种情况。在那种情况下不需要清除/忽略输入流。验证字符串只是数字,将字符串转换回整数。我的意思是,这只是即兴表演。可能有更好的方法。如果您接受浮点数/双精度数,这将不起作用(必须在搜索字符串中添加“.”)。

#include <iostream>
#include <string>

int main() {

    std::string theInput;
    int inputAsInt;

    std::getline(std::cin, theInput);

    while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {

        std::cout << "Error" << std::endl;

        if( theInput.find_first_not_of("0123456789") == std::string::npos) {
            std::cin.clear();
            std::cin.ignore(256,'\n');
        }

        std::getline(std::cin, theInput);
    }

    std::string::size_type st;
    inputAsInt = std::stoi(theInput,&st);
    std::cout << inputAsInt << std::endl;
    return 0;
}

【讨论】:

  • @crush cin 不会将输入解释为字符,而是对其进行解析,但“a”不能解析为整数。除了整数之外,其他也不能。
  • 检查一下,伙计。用消息编译代码。如果你输入'a',它会抛出失败位
  • 看来我已经离开 C++ 太久了。
  • if(!cin) 是有效的,但它隐藏了它实际在做什么。 if (cin.fail()) 做同样的事情,而且更清晰。
  • 应该注意的是,如果输入类似于 10abc,那么 cin.fail 将返回 false。 10 将被解析为 int,而 abc 部分将保留在流中等待读取。
【解决方案2】:

c 中有一个名为isdigit() 的函数。那会很适合你。示例:

int var1 = 'h';
int var2 = '2';

if( isdigit(var1) )
{
   printf("var1 = |%c| is a digit\n", var1 );
}
else
{
   printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
  printf("var2 = |%c| is a digit\n", var2 );
}
else
{
   printf("var2 = |%c| is not a digit\n", var2 );
}

来自here

【讨论】:

  • 所以在变量赋值处更改为字符而不是整数,然后按原样使用其余代码? (并赞成,因为经过轻微调整后答案仍然非常有用)
  • 因为如果您提供字符,istream 将无法插入整数,因此您的变量将包含之前存在的任何数据。
  • @crush OP 想要检查输入是否是整数值而不是数字
  • @brunocodutra : 本来打算发同样的东西
  • "isdigit 用于检查str 中的第一个字符 是否为数字,因此是atoi 将其转换为整数值的有效候选字符。”
【解决方案3】:

如果 istream 插入失败,它会设置失败位。

int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
    std::cout << "I failed, try again ..." << std::endl
    std::cin.clear(); // reset the failed state
}

您可以在 do-while 循环中进行设置,以正确插入正确的类型(在本例中为 int)。

欲了解更多信息:http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly

【讨论】:

  • 正确。我把它留给 OP 来解决,但我想为了清楚起见应该添加它。
【解决方案4】:

你可以使用:

int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}

我很确定它有效。

【讨论】:

    【解决方案5】:

    您可以使用变量名称本身来检查值是否为整数。 例如:

    #include <iostream>
    using namespace std;
    
    int main (){
    
    int firstvariable;
    int secondvariable;
    float float1;
    float float2;
    
    cout << "Please enter two integers and then press Enter:" << endl;
    cin >> firstvariable;
    cin >> secondvariable;
    
    if(firstvariable && secondvariable){
        cout << "Time for some simple mathematical operations:\n" << endl;
    
        cout << "The sum:\n " << firstvariable << "+" << secondvariable 
        <<"="<< firstvariable + secondvariable << "\n " << endl;
    }else{
        cout << "\n[ERROR\tINVALID INPUT]\n"; 
        return 1; 
    } 
    return 0;    
    }
    

    【讨论】:

      【解决方案6】:

      嘿,这是一个老问题,可以使用更好的答案。

      用户输入应该是一个字符串,然后尝试转换为你想要的数据类型。方便的是,这还允许您回答诸如“我的输入是什么类型的数据?”之类的问题

      这是我经常使用的一个功能。其他选项也有,比如在Boost中,但基本前提是一样的:尝试进行字符串→类型转换,观察成功或失败:

      template <typename T>
      std::optional <T> string_to( const std::string& s )
      {
        std::istringstream ss( s );
        T result;
        ss >> result >> std::ws;      // attempt the conversion
        if (ss.eof()) return result;  // success
        return {};                    // failure
      }
      

      使用optional 类型只是一种方法。您也可以抛出异常或在失败时返回默认值。适合你的情况。

      这是一个使用它的例子:

      int n;
      std::cout << "n? ";
      {
        std::string s;
        getline( std::cin, s );
        auto x = string_to <int> ( s );
        if (!x) return complain();
        n = *x;
      }
      std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
      

      限制和类型识别

      当然,为了使其工作,必须有一种方法可以明确地从流中提取您的数据类型。这是 C++ 中事物的自然顺序——即一切照旧。所以这里没有惊喜。

      下一个警告是某些类型包含其他类型。例如,如果您要区分 intdouble,请首先检查 int,因为任何转换为​​ int 的内容也是 double

      【讨论】:

        【解决方案7】:

        我更喜欢使用&lt;limits&gt; 来检查int,直到它通过为止。

        #include 
        #include  //std::numeric_limits
        
        使用 std::cout、std::endl、std::cin;
        
        int main() {
            整数;
            while(!(cin >> num)){ //以正确的方式检查整数的输入格式
                cin.clear();
                cin.ignore(std::numeric_limits<:streamsize>::max(), '\n');
                cout 
            

        【讨论】:

          【解决方案8】:

          在 C++11 及更高版本下,我发现 std::stoi 函数对这项任务非常有用。如果无法执行转换, stoi 将引发 invalid_argument 异常。这可以被捕获和处理,如下面的演示函数“getIntegerValue”所示。

          stoi 函数有第二个参数'idx',它表示字符串中第一个字符在数字之后的位置。我们可以使用 idx 中的值来检查字符串长度并确定输入中是否有除数字之外的任何字符。这有助于消除 10abc 或十进制值等输入。

          这种方法唯一失败的情况是输入中的数字后面有尾随空格,即用户输入数字后输入了很多空格。要处理这种情况,您可以按照this post 中的说明对输入字符串进行 rtrim。

          #include <iostream>
          #include <string>
          
          bool getIntegerValue(int &value);
          
          int main(){
              
              int value{};
              bool valid{};
          
              while(!valid){
                  std::cout << "Enter integer value: ";
                  valid = getIntegerValue(value);
                  if (!valid)
                      std::cout << "Invalid integer value! Please try again.\n" << std::endl;
              }
              
              std::cout << "You entered: " << value << std::endl;
          
              return 0;
          }
          
          // Returns true if integer is read from standard input
          bool getIntegerValue(int &value){
              bool isInputValid{};
              int valueFromString{};
              size_t index{};
              
              std::string userInput;
              std::getline(std::cin, userInput);
          
              try {
                  //stoi throws an invalid_argument exception if userInput cannot be
                  //converted to an integer.
                  valueFromString = std::stoi(userInput, &index);
          
                  //index being different than length of string implies additional
                  //characters in input that could not be converted to an integer.
                  //This is to handle inputs like 10str or decimal values like 10.12
                  if(index == userInput.length()) isInputValid = true;
              }
              catch (const std::invalid_argument &arg) {
                  ;       //you could show an invalid argument message here.
              }
          
              if (isInputValid) value = valueFromString;
          
              return isInputValid;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-09-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-28
            • 2015-11-05
            • 2014-07-25
            • 1970-01-01
            相关资源
            最近更新 更多