Como verificar se a input é um inteiro válido sem nenhum outro caractere?

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

Como posso verificar se o usuário insere um inteiro válido? Neste programa que escrevi acima, se o usuário insere 9 , deve estar correto, no entanto, se o usuário insere 9a por exemplo, ele deve retornar um erro, mas isso não acontece por algum motivo. Como posso corrigir isso?

Como eu fiz isso usando cin.peek ()

 #include  #include  #include  using namespace std; int main() { int x; bool ok; cout <> 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::max(), '\n'); } } if (x == (5 + 4)){ cout << "Correct!" << endl; } else{ cout << "Wrong!" << endl; } return 0; } 

Você pode ler uma string, extrair um inteiro dela e depois certificar-se de que não resta nada:

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

Você tem uma input orientada por linha, então você provavelmente deveria estar usando o getline . Algo como:

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

deve fazer o truque.

Usando isso, seu loop seria:

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

Observe que essa técnica também significa que você não precisa se preocupar em limpar o erro ou ressincronizar a input.

Por que isso acontece, dê uma olhada neste link :

Extrai e analisa os caracteres sequencialmente do stream para interpretá-los como a representação de um valor do tipo apropriado, que é armazenado como o valor de val. Internamente, a function acessa a sequência de input construindo primeiro um object sentinela (com noskipws configurado como false). Então (se bom), ele chama num_get :: get (usando o código de idioma selecionado do stream) para executar as operações de extração e análise, ajustando os sinalizadores de estado interno do stream de acordo. Finalmente, ele destrói o object sentinela antes de retornar.

Então observe o comportamento se você tentar algo assim:

 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 

Se você inserir "a100", ele gera:

 0 0 

tente isto:

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

Referir isto:

Correção de C ++ para verificar se a input é um inteiro

Um que eu vi que funciona para algumas situações é:

  • Leia a input como string. cin >> str
  • Decodifica para number: atoi, ou sscanf, ou stringstream, etc.
  • imprima o número em uma string (usando sprintf ou stringstream)
  • verifique se é igual a ler string. (usando strings ==, não char *)

Rápido e simples de fazer. Usa as regras de quebra de palavras, aceita números negativos, rejeita números transbordantes. Mas rejeita “+10”, que em algumas situações você é feliz, e em alguns você não é.

Se você pode usar o C ++ 11 (e seu compilador tem suporte completo a regex), você também pode usar a biblioteca :

 #include  #include  #include  #include  #include  int main() { std::string line; std::pair 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::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; }