Re: Why doesn't std::cin choke on this?

From: Karl Heinz Buchegger (kbuchegg_at_gascad.at)
Date: 01/05/04


Date: Mon, 05 Jan 2004 16:26:12 +0100

William Payne wrote:
>
> Hello, when I was writing a user-driven test program for a data structure I
> wrote, I encountered an annoying problem. The test program is laid out as a
> menu with several numbered options. The user selects one option by typing in
> its corresponding number (int).

And this is your problem. You read an int.
The simplest thing you can do is to forget the idea of reading an int.
After all, if the user types 2, this is a character just like 'a' or 'b'.
So read everything as character, it simpler then checking the stream for it's
state, getting rid of the invalid input, clearing that error state and thus
make the stream workable again.

> Depending on the choice he made, he may be
> asked to provide another integer (or no input at all).

Having no input at all is tricky when you try to read an int. Again: If you
read in a string, this becomes trivial.

> So all the user does
> is entering integers. I don't want the user to be able to cause problems or
> crashes by providing invalid input, but he is despite my error checking.
> Here follows output from my program here boiled down to a "minimum":
> $ ./test
> 1 - choice one
> 2 - choice two
> 3 - exit program
> What is your choice? 1
> Enter integer to be doubled: 2+2
> 2 doubled is 4
> 1 - choice one
> 2 - choice two
> 3 - exit program
> What is your choice? Enter integer to be squared:
>
> In this test run the user presses 1 when asked for which choice he wants in
> the menu. But when asked to input an integer he enters 2+2, and cin does not
> go into an error state

why should it?
Streams are defined that they try to read as much as possible to fullfil the
request. The request was to read an int, thus everything that can be an int
is taken from the stream, in your case the first '2'. The rest is left in the
input queue and is waiting for your program to read it.

> but leaves the last '2' plus a newline in the stream,
> triggering a new menu option (the '+' was eaten by a call to cin.get() which
> is supposed to get rid of the newline. Now how can I fix my code so it
> doesn't allow this?

look up the ignore() function of the stream.
But again, it's simpler to *not* read the users input as an int. Read it as a string,
then try to extract the number from the string. This way the user can enter whetever
he likes (even no 'numer' at all), and nothing special will happen: The users input
is read as string and your number detection function will not be able to extract
a number from that and thus your program will emit an error. But in no case the
stream has entered a fail state and must be made useable again (for extracting
something from a string, the stringstreams are a handy tool).

> And why doesn't cin choke on 2+2 when asked to enter an
> integer?

See above. It's defined to be that way. If you had entered: '*2' it would
have choked, because '*' is not a valid starting character for an integer.

-- 
Karl Heinz Buchegger
kbuchegg@gascad.at


Relevant Pages