• Create Account

## C++ Verify user inputs a number

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

18 replies to this topic

Posted 13 March 2004 - 02:10 PM

Hi all, I'm trying to make sure a user types in a number for a int varible. Ive tried useing isnum and isdigit but they don't seem to like working with Int's only Char's ... anyone else have any idea? here is a simple idea of what Im trying to do...
int Soc;

cout << "enter soc" << end;
cin >> Soc;
if (isdigit(Soc))
cout << "ok";
else
cout << "wrong";
}

[edited by - justaddwater on March 13, 2004 9:11:41 PM]

### #2Xai  Members

Posted 13 March 2004 - 02:22 PM

the reason is, the >> operator ALREADY knows the type of your var ... and CAN ONLY WORK WITH input of the correct type ...

so using "char" you can get each character and check for digits ... but using "int" you cannot, because doing this:

int num;
cin >> num;

reads in ONLY AN INT already ... if the user types "65" it works, or "-1235433", or even "0x0fa3" ... and if the user types "45.23" then the "45" part is read, but the ".23" is still in the buffer ... and here''s the important part .. if they type "hello53" .. the system blows up!

the formatted stream readers do NOT guarantee the formats are correct, and do NOT handle errors well ... they leave it to you to correctly tell them what to expect ... which oftens sucks ... as you''ve found out.

What you must do to perform input error / format checking is read in UNFORMATED (or less directly formatted) input - for example if you tell the user to type number and press enter, then you read a line, and then validate the chars in that line, and THEN convert the validated input to an int. I know it sucks, but that''s just how it works ...

and if you want the user to type a points like:

34,45

then you also would read the whole line, and validate and probably parse and normalize the data ... meaning you will accept spaces around the numbers - and discard them ... and then feed each of the two strings "34" and "45" to be converted to ints ... and used. Of course in the case where the user types unexpected characters, or one one nubmer, or 2 commas or whatnot ... you should reject the input of course (and take whatever exception handling actions you want ... like prompting again) ...

### #3ForeverStarlight  Members

Posted 13 March 2004 - 02:59 PM

quote:
int num;
cin >> num;

reads in ONLY AN INT already ... if the user types "65" it works, or "-1235433", or even "0x0fa3" ... and if the user types "45.23" then the "45" part is read, but the ".23" is still in the buffer ...

If you do not care about the above case there is an easier way,

When the user enters something that causes cin to "blow up", this can be detected:

cin >> num;

if(cin.good())
{
//everything ok
}
else
{
//Everything not ok
cin.clear(); //reset status bits (including the fail bit)
}

### #4fallenang3l  Members

Posted 13 March 2004 - 03:03 PM

int num;while (cout << "Enter a number: " && !(cin >> num)){    cout << "That''s not valid input. Try again" << endl;    cin.clear();    cin.ignore(numeric_limits<streamsize>::max(), ''\n'');}

Posted 13 March 2004 - 03:17 PM

fallenang-

Your code works fine with one problem, if I enter a mixed number, say HHJ876 it accepts it... any ideas?

Thanks everyone for your ideas, I appreciate the quick feedback!!

Posted 13 March 2004 - 04:07 PM

...one more thing I can't remeber what the command is to clear the input buffer? i remember it is "/something" any ideas on the something?

[edited by - justaddwater on March 13, 2004 11:17:15 PM]

### #7fallenang3l  Members

Posted 13 March 2004 - 04:53 PM

quote:
Original post by Justaddwater
fallenang-

Your code works fine with one problem, if I enter a mixed number, say HHJ876 it accepts it... any ideas?

Thanks everyone for your ideas, I appreciate the quick feedback!!

I compiled it just in case, and keying ''HHJ876'' causes it to print my error message. I have no clue why it doesn''t work for you, but it most definitely should. What compiler are you using and what headers are you including?

Posted 13 March 2004 - 04:56 PM

Visual studio dot net

and your right HHJ876 gets caught, the problem is with 876HHJ (and me typeing dyslesicly..uhhh not to mention my spelling)

#include <ctime>
#include <cctype>
#include <limits>
#include <iomanip>
#include <iopstream>

[edited by - justaddwater on March 13, 2004 11:57:42 PM]

### #9Xai  Members

Posted 13 March 2004 - 05:02 PM

the key is in the idea of the reader ... the reader stops reading upon encountering an input it isn''t wanting to process ... so, like i said about the float situation (where the user types "45.23" and what is left in the buffer (waiting to be read by the next read call - is ".23"

In your case, the first call reads the numbers, but just leaves the text for later.

this is no different than when you read characters, and the user types "hello[ENTER]" ... the first call gets "h" and leaves the "ello" in the queue ... so a loop would build the string ... but if you only wanted the user to type 1 character, and they typed "hello", if your next call innocently asked them to enter a number, it would error out, because the "ello" are the first things in the queue

... wish I could remember what you can do to throw those characters away safely ...

### #10fallenang3l  Members

Posted 13 March 2004 - 05:22 PM

I think this should work nicely.
	int num;	while (cout << "Enter a number: " && !(cin >> num) || cin.peek() != ''\n'')	{    		cout << "That''s not valid input. Try again" << endl;		cin.clear();		cin.ignore(numeric_limits<streamsize>::max(), ''\n'');	}

Posted 13 March 2004 - 05:53 PM

with your code how would i modify it to do a check? I cant tell where to put in the line

if (num < 1) output error and redo

[edited by - justaddwater on March 14, 2004 1:29:09 AM]

### #12fallenang3l  Members

Posted 14 March 2004 - 04:07 AM

In the conditional.

Posted 14 March 2004 - 10:21 AM

Ive never seen a statement written like that before with the cout in the while condison , so im not sure hoe you mean I could add it in there...

### #14Zahlman  Members

Posted 14 March 2004 - 07:50 PM

The "cout << foo" part returns a true value, so it doesn''t affect breaking out of the loop - it''s used for its side effect, i.e. printing the text. The other guy is putting it there so that text will output before the input is checked, even off the first iteration.

All you need to do is add all of your filters to that line, chained with logical OR''s.

so at a high level it looks like
while (do output and report true) and ((input was not an integer) or (next character after the input isn''t a newline) or (anything else that would render the input invalid <-- YOU FILL IN THIS PART))  report error; // because "do output and report true" was of course true, and one of the filters failed, making that part true as well  clear the failed state of the input stream; // so we don''t report an error next time  skip ahead in the input stream to the next newline; // so we don''t re-parse the invalid data and get stuck in a loop

Posted 15 March 2004 - 06:49 AM

I understand now, thanks for the info and the neat new trick for i/o (new to me!)

Posted 15 March 2004 - 03:31 PM

I added this to my program and it worked great, but there is one problem now with it.

When the num < 1 triggers you have to hit CR twice to get back to prompt, when any other condishon triggers it loops right back to prompt

while (cout << "Enter Quantity: " && !(cin >> Quantity)  || (Quantity < 1) || cin.peek() != '\n'){    	cout << "Quantity must be  whole positive number!" << endl;    	cin.clear();	cin.ignore();	cin.ignore(numeric_limits<streamsize>::max(), '\n');}

[edited by - justaddwater on March 15, 2004 10:32:21 PM]

[edited by - justaddwater on March 15, 2004 10:33:39 PM]

[edited by - justaddwater on March 16, 2004 6:01:15 PM]

### #17Fruny  Moderators

Posted 16 March 2004 - 11:20 AM

Unpatched VC6?

Go here and here to fix it.

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan

### #18MaulingMonkey  Members

Posted 16 March 2004 - 11:38 AM

quote:
Original post by Justaddwater
I added this to my program and it worked great, but there is one problem now with it.

When the num < 1 triggers you have to hit CR twice to get back to prompt, when any other condishon triggers it loops right back to prompt

*snip*

Err, what''s with the two ignore lines?

The program works perfectly for me if you comment out/delete the first line.