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

How can I check if the user inputs a valid integer? In this program I wrote above, if the user inputs 9, it should be correct, however, if the user inputs 9a for example, it should return an error, but it doesn't for some reason. How can I correct it?

How I did it using 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;
}
user2699298
  • 1,446
  • 3
  • 17
  • 33

7 Answers7

7

You could read a string, extract an integer from it and then make sure there's nothing left:

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
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
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();
}
Constantin
  • 8,721
  • 13
  • 75
  • 126
3

You have a line oriented input, so you should probably be using getline. Something like:

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

should do the trick.

Using this, your loop would be:

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

Note that this technique also means that you don't have to worry about clearing the error or resynchronizing the input.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
3

For the reason this happens, take a look at this link:

Extracts and parses characters sequentially from the stream to interpret them as the representation of a value of the proper type, which is stored as the value of val. Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to false). Then (if good), it calls num_get::get (using the stream's selected locale) to perform both the extraction and the parsing operations, adjusting the stream's internal state flags accordingly. Finally, it destroys the sentry object before returning.

Then observe the behavior if you attempt something like this:

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

If you input "a100" instead, it outputs:

0
0
2

try this:

std::string input;
std::cin >> input;

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

Refer this :

C++ Fix for checking if input is an integer

Community
  • 1
  • 1
bgs
  • 3,061
  • 7
  • 40
  • 58
1

One I have seen that works for some situations is:

  • Read the input as string. cin >> str
  • Decode to number: atoi, or sscanf, or stringstream, etc.
  • print the number into a string (using sprintf or stringstream)
  • check if its equal to read string. (using strings ==, not char*)

Quick and simple to do. Uses the Cin>>str word breaking rules, accept negative numbers, rejects overflowing numbers. But it does reject "+10", which in somesituations you are happy wiht, and in some you are not.

RichardPlunkett
  • 2,998
  • 14
  • 14
1

If you can use C++11 (and your compiler has full regex support), you can also use the <regex> library:

#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;
}
Zac Howland
  • 15,777
  • 1
  • 26
  • 42