There's a simple C++ idiom you can use to read an object of any type with an extraction operator and check to see if it's been read successfully. It's only a couple of lines:
int n = 0;
if( std::cin >> n )
{
std::cout << "I've read a number, it's a " << n << std::endl;
}
else
{
std::cout << "Ooops, whatever you typed it wasn't a number..." << std::endl;
std::cin.clear();
std::string junk_line;
std::getline( std::cin, junk_line );
}
The important bit is the line that does the read. It relies on two things:
- extraction operators return the stream they're operating on after the operation, this allows you to string extractions together.
- stream objects have a conversion operator to bool [1]. If this is false the stream is jammed up for some reason, usually because a conversion has failed or because the stream has hit an end of file condition. [2]
So when you do the read the one of the following things happen:
- the next characters out of the stream can represent an integer. Yay! The stream is in a good state and the condition is true.
- the next characters out of the stream can't represent an integer. Boo! The stream is clagged up and can't be read from until the error state is cleared. To do that you clear the stream state and then read and discard the line that's caused the problem - which the block of code after the error message.
Anyway, I hope this helps you write C++ that looks like C++ and not the slightly wonky C you've ended up using. If you're interested in C++ streams then I'd recommend reading "Standard C++ IOStreams and locales: Advanced programmer's guide and reference" By Angelika Langer and Klaus Kreft. It's a dry but informative read that will tell you everything you want to know about streams and loads more you don't.
Cheers,
Ash
[1] Actually it's not straight to bool, it's to a type of function pointer which is convertible to bool. Don't worry about details like that for now though.
[2] Again, this aint the whole story but enough to get you through your current problem.