I'm tring to understand what is happening here.
I have this simple code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
...
int number;
do{
try{
cout << "Enter number [-1 to exit]:";
cin >> number;//<-Won't prompt here for new imput if user type a letter by mistake
cout << "\n Read Number, " << n << ".\n";
}catch(const std::string& ex){
cout<< "Ups...! "<< endl<< ex;
}
}while( number != -1 );
So let me understand why:
* If the user type a character by mistake the program will not prompt for new input.
* If the user in the very first iteration types a number, and in the next iteration types a char, the var (number) will keep the first typed value and cin will not prompt again for a value.
In both scenarios it causes a infinite loop and no exception is thrown.
> If the user type a character by mistake the program will not prompt for new input
Because the initial input was rejected (a character is not an integer, and you're using integer-only input at line 3). It is there inside cin, waiting for you to either discard it or to reprocess it.
> If the user in the very first iteration types a number, and in the next iteration types a char, the var (number) will keep the first typed value
That's the older C++ behavior: when the input is rejected, the variable keeps its original value. Newer compilers change it to zero when that happens. But either way, the input is rejected and needs to be reprocessed or discarded before any new input can take place.
By the way, since nothing is throwing any strings in your code, try/catch does nothing.
Yea try/catch in C++ isn't as simple as it is in C#. You must actually throw most exceptions although you can catch any exception by using the elipsis (...)
Your best bet is to read in character by char and try to cast them to an int. That way your program won't fail when an invalid int is entered.
You can use the library method isdigit(char c) to determine if a char is a digit. If it is, you can cast to an int using the C library method atoi.
You could also check is the stream failed and manually clear it yourself. Let me know if you need some example code.
EDIT - just try this, it's as simple as it gets for your situtation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int main()
{
int input;
do
{
cin >> input;
if (!cin)
{
cin.clear();
cin.ignore(256, '\n');
}
}
while (input != -1);
return 0;
}
Your best bet is to read in character by char and try to cast them to an int. That way your program won't fail when an invalid int is entered.
You can use the library method isdigit(char c) to determine if a char is a digit. If it is, you can cast to an int using the C library method atoi.
Horrible suggestion. In the code, input is never initialized to any value, but the loop depends on it's value (which is the wrong thing to loop on anyway.)
#include <sstream>
#include <string>
#include <iostream>
#include <limits>
#include <stdexcept>
// utility function. Keeps the loop logic
// a little cleaner in the get_int functions.
template <typename T>
std::istream& get_input(charconst* prompt, T& input)
{
std::cout << prompt ;
return std::cin >> input ;
}
// get an int directly.
int get_int_1(charconst* prompt)
{
int input ;
while ( !get_input(prompt, input) )
{
// clear error state:
std::cin.clear() ;
// discard the line of input:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') ;
}
return input ;
}
// read in a string and parse the string for an int.
int get_int_2(charconst* prompt)
{
std::string input ;
while ( get_input(prompt, input) )
{
std::istringstream is(input) ;
int input_as_int ;
if ( is >> input_as_int )
return input_as_int ;
std::cout << '"' << input << "\" is not valid.\n" ;
}
// A failure from get_input means something outside the normal realm of events
// for console input has occurred -- possibly stdin was redirected to a file,
// and we ran into eof, for example. Let's consider it exceptional.
throw std::runtime_error( "Unexpected extraction error in get_int_2\n") ;
}
int main()
{
int anInt = get_int_1("Enter a number: ") ;
std::cout << anInt << " is the number you entered.\n" ;
anInt = get_int_2("Enter another number: ") ;
std::cout << anInt << " is the second number you entered.\n" ;
}