如何检查输入是否是一个没有任何其他字符的有效整数?

时间:2013-11-29 13:42:55

标签: c++ validation integer

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

7 个答案:

答案 0 :(得分:7)

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

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
}

答案 1 :(得分:3)

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();
}

答案 2 :(得分:3)

你有一个面向行的输入,所以你可能应该使用 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;
}

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

答案 3 :(得分:3)

出于这种情况的原因,请查看此link

  

从流中依次提取和解析字符   将它们解释为正确类型值的表示,   它被存储为val的值。在内部,函数访问   输入序列首先构造一个哨兵对象(用   noskipws设置为false)。然后(如果好),它调用num_get :: get(using   流的选定区域设置)执行提取和   解析操作,调整流的内部状态标志   因此。最后,它会在返回之前摧毁哨兵对象。

如果您尝试这样的事情,请观察行为:

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

答案 4 :(得分:2)

试试这个:

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

答案 5 :(得分:1)

我发现在某些情况下适用的是:

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

快速而简单。使用Cin&gt;&gt; str字断开规则,接受负数,拒绝溢出的数字。但是它确实拒绝了“+10”,这在某些情况下你会感到高兴,有些则不是。

答案 6 :(得分:1)

如果您可以使用C ++ 11(并且您的编译器具有完整的正则表达式支持),您也可以使用<regex>库:

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