Validation Problems

I know this might have been discussed many times and I looked over the solutions but it's really messy...
I just don't understand why there is no simple type validation in c++, couldn't it be like :
-----------------
int a;
cin >> a;
if (type(a),int){
dothis()
else
cin >> a;
-----------------
All i want is <a> to be an integer or re-enter <a> if it isn't.
I looked on google for hours now and everyone has a different way for validation, most of them takes over 5 lines of code...

Is there a simple way to validate <a> to be an integer without my program crash, having fatal error,etc. Tell me how you guys do with explanation if possible. (Also is it possible to create a command to verify that type is integer because I use it a lot). thank you.





Well, that's really simple. Because a is always an int, you declared it as such after all. What you really want to know is not whether a is an integer or not, but whether the user has entered an integer number or not. That's 2 completely separate issues.
You can use this as part of your input validation strategy.
1
2
3
4
5
6
7
8
9
10
int a;

if(cin >> a)
{
    // user entered an int
}
else
{
    cin.clear(); // clear the error flag
}
*tries to resist urge to bring up how this is a common problem that shows the difficulty of console IO and is partialy why starting with the console is a bad idea*

*fails*

Anyway, it's been forever since I've used iostream for this purpose, but IIRC you can check if the last extraction was "good" simply by testing cin in an if statement. If it fails, you can clear whatever is left in the buffer with cin.ignore, then clear the flags with cin.clear, and then you're good to go for another read.

Not exactly the most simple thing in the world... but I *think* it'll work. Note it's untested so you might want to try it out for yourself. Like I said I hardly ever use cin for input.

1
2
3
4
5
6
7
8
9
10
11
12
13
int GetIntFromCin()
{
  int r;
  cin >> r;
  while(!cin)
  {
    cin.ignore(999999);  // clear the buffer
    cin.clear();  // clear the state
    cout << "Please enter an integer:  ";
    cin >> r;
  }
  return r;
}



EDIT: Galik beat me to the punch, but I'm pretty sure cin.clear() alone will not solve the problem because the bad input remains in the buffer. cin.ignore is what clears the buffer. Contraty to its name, cin.clear() doesn't actually clear anything.
Last edited on
Don't think there's much need for a more elegant way. Chances are that console-input won't be asked from anyone who isn't the developer himself. Messing up your own input is a problem no code can fix.
I disagree, Gaminic.

Input validation is a huge issue and should be properly addressed in every program, regardless of where the input is coming from.

Under no circumstances should bad input cause your program to hang/crash/behave weirdly.

EDIT: (actually, I suppose it's not import for quickie apps that you don't really care about) /EDIT
Last edited on
Contraty to its name, cin.clear() doesn't actually clear anything.


Well, it does clear the error flags. Though something like "clearErrorFlags" would have been more appropitiate.
Thank you for the answers guys! Galik and Disch that's what I needed.
Galik you're method works very well with 'if', I'll try it using 'while' now.
Disch, you're method seems right but somehow it spams "Please enter an integer" when I enter letters for the 'r'. It doesn't allow me to cin a new value for 'r', do you know how to fix that?



I just have another question :
-What is the difference between the buffer and state ( cin.ignore and cin.clear)?

Thank you!
Dish had the solution except he calls ignore() before clearing the stream error. That's probably why it didn't work for you. Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

int main()
{
	int i;

	std::cout << "Please input an int: ";

	while(!(std::cin >> i))
	{
		std::cin.clear();  // re-enable std::cin by clearing the error
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore the invalid input
		std::cout << "Not an int, please try again: ";
	}

	std::cout << "i: " << i << '\n';
}

Last edited on
Sorry about that. Like I said I didn't test it, and I virtually never use iostream, so... =/
thank you again!
we have to use iostream since we just began c++, I guess we will learn more input later on.

I don't really understand what to put in the ignore...just a high value? Is there any ways to ignore the whole input? Because if I read it right, I understand that if I write for example ignore(200) and the user types 250 characters it will only ignore the first 200.

Topic archived. No new replies allowed.