【问题标题】:How to check if the input is a valid integer without any other chars?如何检查输入是否是没有任何其他字符的有效整数?
【发布时间】:2013-12-15 17:37:36
【问题描述】:
#include <iostream>
#include <limits>

using namespace std;

int main()
{
    int x;
    cout << "5 + 4 = ";
    while(!(cin >> x)){
        cout << "Error, please try again." << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    if (x == (5 + 4)){
        cout << "Correct!" << endl;
    }
    else{
        cout << "Wrong!" << endl;
    }
    return 0;
}

如何检查用户输入的整数是否有效?在我上面写的这个程序中,如果用户输入9,它应该是正确的,但是,如果用户输入9a,它应该返回一个错误,但由于某种原因它没有。我该如何纠正?

我是如何使用 cin.peek() 做到的

#include <iostream>
#include <limits>
#include <stdio.h>

using namespace std;

int main()
{
    int x;
    bool ok;
    cout << "5 + 4 = ";

    cin >> x;

    while(!ok){
  cin >> x;

  if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n')){
  ok = true;
  }
  else{
  cout << "Error, please try again." << endl;
  cin.clear();
  cin.ignore(numeric_limits<streamsize>::max(), '\n');
  }
    }

    if (x == (5 + 4)){
  cout << "Correct!" << endl;
    }
    else{
  cout << "Wrong!" << endl;
    }

    return 0;
}

【问题讨论】:

    标签: c++ validation integer


    【解决方案1】:

    试试这个:

    std::string input;
    std::cin >> input;
    
    if ( std::all_of(input.begin(), input.end(), std::isdigit) )
    {
         //input is integer
    }
    

    参考这个:

    C++ Fix for checking if input is an integer

    【讨论】:

    • 因此“-10”不是一个有效的整数? :)
    • 错误:all_of 未在此范围内声明。我需要 C++ 的代码,而不是 C++11 的有符号/无符号整数。
    • @user2699298 C++11 C++。我猜你的意思是你需要 C++03。
    【解决方案2】:
    bool isIntegerNumber(const std::string& string){
      std::string::const_iterator it = string.begin();
      int minSize = 0;
      if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
        it++;
        minSize++;
      }
      while (it != string.end() && std::isdigit(*it)) ++it;
      return string.size()>minSize && it == string.end();
    }
    

    【讨论】:

      【解决方案3】:

      您可以读取一个字符串,从中提取一个整数,然后确保没有任何内容:

      std::string line;
      std::cin >> line;
      std::istringstream s(line);
      int x;
      if (!(s >> x)) {
        // Error, not a number
      }
      char c;
      if (s >> c) {
        // Error, there was something past the number
      }
      

      【讨论】:

      • 你也可以peek()
      • 您通常也希望跳过尾随空格,因为用户看不到它,并且如果发生错误也不会理解为什么会出现错误。
      • @JamesKanze 不应该有任何尾随空格 - 我使用 &gt;&gt; 来提取字符串(就像 OP 所做的那样),而不是 getline()
      • 啊,是的。但这并不符合他似乎想要做的事情(因为当出现错误时他会跳到行尾)。
      【解决方案4】:

      你有一个面向行的输入,所以你可能应该使用 getline。比如:

      bool
      getIntFromLine( std::istream& source, int& results )
      {
          std::string line;
          std::getline( source, line );
          std::istringstream parse( source ? line : "" );
          return parse >> results >> std::ws && parse.get() == EOF;
      }
      

      应该可以解决问题。

      使用这个,你的循环将是:

      while ( !getIntFromLine( std::istream, x ) ) {
          std::cout << "Error, please try again." << std::endl;
      }
      

      请注意,这种技术也意味着您不必担心 关于清除错误或重新同步输入。

      【讨论】:

        【解决方案5】:

        出现这种情况的原因,看看这个link

        从流中按顺序提取和解析字符到 将它们解释为正确类型的值的表示, 它存储为 val 的值。在内部,函数访问 通过首先构造一个哨兵对象(使用 noskipws 设置为 false)。然后(如果好的话),它调用 num_get::get (使用 流的选定语言环境)以执行提取和 解析操作,调整流的内部状态标志 因此。最后,它在返回之前销毁哨兵对象。

        如果你尝试这样的事情,然后观察行为:

        int x = 0;
        
        cin >> x;
        std::cout << x << std::endl;
        std::cout << cin.good() << std::endl;
        
        g++-4.8 -std=c++11 -O3 -Wall -pedantic -pthread main.cpp && echo "900a100" | ./a.out
        // Output:
        // 900
        // 1
        

        如果你输入“a100”,它会输出:

        0
        0
        

        【讨论】:

          【解决方案6】:

          我见过适用于某些情况的一种方法是:

          • 将输入读取为字符串。 cin &gt;&gt; str
          • 解码为数字:atoi、或sscanf、或stringstream等
          • 将数字打印成字符串(使用 sprintf 或 stringstream)
          • 检查它是否等于读取的字符串。 (使用字符串 ==,而不是 char*)

          做起来又快又简单。使用 Cin>>str 分词规则,接受负数,拒绝溢出数字。但它确实拒绝“+10”,在某些情况下你会感到高兴,而在某些情况下你会不高兴。

          【讨论】:

          • 如果您可以使用正则表达式,那么最后一部分不是问题。
          【解决方案7】:

          如果您可以使用 C++11(并且您的编译器完全支持正则表达式),您还可以使用 &lt;regex&gt; 库:

          #include <iostream>
          #include <limits>
          #include <regex>
          #include <string>
          #include <utility>
          
          int main()
          {
              std::string line;
              std::pair<int, bool> value = std::make_pair(0, false);
              std::cout << "5 + 4 = ";
              while (!value.second)
              {
                  while (!std::getline(std::cin, line))
                  {
                      std::cout << "Error, please try again." << std::endl;
                      std::cin.clear();
                      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                  }
          
                  if (!std::regex_match(line, std::regex("(\\+|-)?[[:digit:]]+")))
                  {
                      std::cout << "Error, please try again." << std::endl;
                  }
                  else
                  {
                      value = std::make_pair(std::stol(line), true);
                  }
              }
          
              if (value.first == (5 + 4))
              {
                  std::cout << "Correct!" << std::endl;
              }
              else
              {
                  std::cout << "Incorrect!" << std::endl;
              }
          
              return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 2021-10-03
            • 2022-11-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-28
            • 2013-12-10
            • 2023-03-30
            相关资源
            最近更新 更多