I always recommend reading the data in as a string, validating it, and then converting to the appropriate type using a stringstream. Maybe this can be made into an FAQ if it isn't already?
Code:
# include <sstream>
# include <iostream>
# include <string>
using namespace std;
int main()
{
string strNum;
// loop until valid input received
while (true) {
cout << "Enter a number: ";
// get the number from standard input
cin >> strNum;
// look for the first character that does not match
size_t pos = strNum.find_first_not_of("1234567890.-");
// If we find a non-matching character, it's invalid
// so we retry
if (pos != string::npos) {
cout << "Invalid input, try again" << endl;
continue;
}
else break;
}
double d;
stringstream ss;
// One downside, but not the end of the world, is if the
// user enters a number with multiple decimal points, or
// a number with a minus sign in the wrong place, the
// double will be truncated at that point. But at least it
// won't blow up. You can write more intelligent code to
// check the input string if you want to.
ss << strNum;
ss >> d;
cout << "You entered " << d << endl;
return 0;
}