0

Currently having issues creating an integer validation loop in my code.

Trying to validate for an integer, however this code fails to work if you input, for example the string '22a' it sets trial_no as 22. Is there any way to check that every charachter input is indeed a string, such that '22a' or '2a2' would be considered erroneous and the loop would continue until a valid integer was input?

int trial_no;

bool valid = false;

while(!valid) 
{
    valid = true; //assume trial_no will be an integer
    cout << "Enter the number of die throws to simulate" << endl;
    cin >> trial_no;

    if(cin.fail()) // exit loop condition is dependent on trail_no being a valid integer
    {
        cin.clear(); //corrects stream
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); //skips left over stream data (numeric_limit
        // is in case user enters more than one letter))
        cout << "Please enter an integer value" << endl;
        valid = false; //cin not an integer so loop goes round to try again
    }
}
2
  • 3
    Read it in as a std::string and then convert it to an integer. If the conversion fails, it's not an integer. Commented Oct 23, 2017 at 14:24
  • Possible duplicate of How do I check if a C++ string is an int? Commented Oct 23, 2017 at 14:25

1 Answer 1

0

Arguably the best way is to read the entire line as a string and utilize the std::stoi function:

#include <iostream>
#include <string>
int main() {
    std::cout << "Enter an integer: ";
    std::string tempstr;
    bool valid = false;
    std::getline(std::cin, tempstr);
    try {
        int result = std::stoi(tempstr);
        std::cout << "The result is: " << result;
        valid = true;
    }
    catch (std::invalid_argument) {
        std::cout << "Could not convert to integer.";
        valid = false;
    }
}

As pointed out in the comments, this function can also throw a std::out_of_range exception. This assumes your compiler is C++11 (+) capable. If not, go down the std::stringstream route:

std::string tempstr;
std::getline(std::cin, tempstr);
std::stringstream ss(tempstr);
int result;
bool valid = false;
if (ss >> result) {
    valid = true;
}
else {
    valid = false;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Please note that std::stoi could throw a std::out_of_range exception too. Besides, it may be useful to retrieve the number of characters processed and to pass the base.
This actually doesn't answer the question since stoi's output of "22a" is still 22.
@xyious The answer is a receipt and a nudge in the right direction. Getting into input stream and std::cin internals is often not the way to go.
But it seems the std::cin methods shown in other questions and this answer with stoi both don't chop off the unwanted alphabet characters for integer input.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.