Input validation

So far I have been using while loops and do while loops for input validation. This is good for simple programs, but if I put in characters when I need a int or a int when a I need a float it crashes my program.

My question is: What is the best way to validate input so it doesn't crash the program???

The program below shows a function in my program. For example, if I enter "ffff", it will output:

"Enter choice: Enter choice: Enter choice: Enter choice: "

If I enter "fff" it will show "Enter choice: " three times.

I want perfect input validation.


1
2
3
4
5
6
7
8
9
10
11
12
13
 char choice_fun(){
	
	char choice;
	
	do{
		
	cout << "Enter choice: ";
	cin >> choice;
	
	}while(choice != 'A' && choice != 'B' && choice != 'C');

	return choice;
}
That is because cin is trying to read the f's one character at a time, because only one letter fits into char. I don't know if this is the best solution, but you could make choice a string instead and use getline for input.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
using namespace std;

int main() {
	string choice;

	do{
		cout << "Enter choice: ";
		getline(cin, choice);
	} while(choice != "A" && choice != "B" && choice != "C");

	cout << "Your choice is " << choice << '.' << endl;
}


This isn't the program you are trying to make, but it has all the same elements so you can see how it works.

This is good validation because it works if the user enters in multiple characters as one word, but also works if the user enters in several words (such as "a b c") because of the use of getline.
Last edited on
Try this

1
2
3
4
5
6
7
8
9
10
11
12
13
char choice_fun(){

	char choice;

	do{

	cout << "Enter choice: ";
    cin.ignore();//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	cin >> choice;
	}while(choice != 'A' && choice != 'B' && choice != 'C');

	return choice;
}
heyyouyesyouiloveyou I cannot use a string because I need to put that value into a switch statement. Thank you for the input though.
@OP
You could checkout the fail bit in the standard input stream whether it has been set.

Aceix.
Wait, why do you have to use letters? Your choices could be 1, 2, 3 instead of A,B,C. Than you could still use getline with cin and integers work with case statements.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
using namespace std;

int main() {
	int choice;

	do{
		cout << "Enter choice: ";
		cin >> choice;
		cin.clear();
		cin.ignore(INT_MAX, '\n');
	} while(choice != 1 && choice != 2 && choice != 3);

	cout << "Your choice is " << choice << '.' << endl;
}


The cin.clear() and cin.ignore() will ignore everything after the first number. The only input that causes issue is a correct input and then an incorrect one.

For example, inputting "3 56" will still let the program output "Your choice is 3."

But if you input "56 3", it asks again.
Last edited on
I already know how to do it using numbers. I want to learn how to do it with characters and strings.
For single characters, you have two options:
1) If the user inputs more than one character, reject the input and prompt the user for a new input, or
2) Just take the first character the user inputs and discard whatever else the user might have entered after that (if anything).

For #2, you can just do
1
2
3
char ch;
cin >> ch; // Grab the first character
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Need #include <limits> for this 

The third line there just tells cin to discard as many characters in the input stream as possible until it reaches a newline character (from the user pressing Enter).
http://www.cplusplus.com/reference/istream/istream/ignore/

For #1, you can use cin.get() to read the next character in the input stream. If the user only entered one character, then the next character should be the newline character ('\n'); otherwise, it'll be something else.
1
2
3
4
5
6
7
8
9
10
11
12
char ch;
while (true)
{
    cin >> ch; // Grab the first character
    if (cin.get() != '\n') // Look at the next character
    {
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Clear the input stream
        cout << "Hey! Only one character, please: ";
    }
    else
        break;
}

(or something similar to this)

For strings, just use a similar loop so that if the user enters something that you don't want, then go back and get a new input.
long double main thank you for the response.
Topic archived. No new replies allowed.