0

I'm currently working on a small project to learn (and for fun) and need a while-loop to check if a user's input is one of the integers 1, 2, 3, 4, or 5. What is the best way to do this? Here's my basic idea in code, but it's not quite working:

std::cin >> input;

while (cin.fail() == true || input != 1 && input != 2 && input != 3 && input != 4 && input != 5){
    std::cout << std::endl "The valid choices are 1, 2, 3, 4, and 5. Please choose: ";
    std::cin >> input;
    std::cout << std::endl;
}

This only works if it's a digit above 5, but fails if I enter a letter. How can I use cin.fail() to validate correctly?

4
  • 1
    Must it be a for loop? Commented Feb 15, 2016 at 23:48
  • Whoops, meant to say while loop. Thanks for catching that. Now changing it. Commented Feb 15, 2016 at 23:48
  • 1
    Also the reason that it fails is because input is presumably an int while you are entering a character. This is quite logical behaviour. Commented Feb 15, 2016 at 23:49
  • I do want cin to fail, but then I need that fail to trigger the while loop to ask again for new input. Commented Feb 15, 2016 at 23:50

2 Answers 2

1

First

#include <limits> 

to get max streamsize. Then flip some of the logic around

while (!std::cin >> input ||  // didn't read valid input
       input < 1 || // number too small
       input > 5) // number too large
{
    std::cout << std::endl "The valid choices are 1, 2, 3, 4, and 5. Please choose: ";

Then clear the stream error and any other crap the user typed in

std::cin.clear();
std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');

Finally ask for a redo

    std::cin >> input;
    std::cout << std::endl;
}

What this won't catch:

1.23

cin will stop reading at the '.' because it's not found in an integer and happily return 1. Ooops.

1a

Same problem

1 holy bad input, Batman!

Similar problem. cin stops at the space.

What you really want to do is something that gets the whole input line from the user with std::getline and then uses std::stoi to make sure that it is all an int

Sign up to request clarification or add additional context in comments.

Comments

1

Assuming that input is an integer, failures will happen when it reads in a string/char. What you need is

cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');

in the body of your while loop since when it fails the stream closes, so you need to clear it.

To expand a bit, the cin.clear() just clears the stream, and then the rest of the line is ignored in the cin.ignore(). It will ignore the maximum possible line size so it's the most correct, but most programs can get away with just putting some huge number in there instead.

Comments

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.