0

I want the user to enter a positive double variable. If they enter anything else, I want the program to loop and continue to ask them to enter a number instead of getting an error and closing. I made an infinite loop with a conditional statement and a break. For some reason if they enter something other than a positive number it infinitely asks for the the radius. Can someone help me with this?

for(;;) {
    cout << "Radius: ";
    cin >> radius;
    if(radius > 0){
        break;
    }
}
Barry
  • 286,269
  • 29
  • 621
  • 977
Suds2
  • 241
  • 2
  • 5
  • 14

2 Answers2

3

You can simply check the stream state of cin:

    double radius;
    for(;;) {
        cout<<"Radius: ";
        if(!(cin>>radius) || radius < 0.0) {
             cout << "Invalid input, please enter a positive double value." << endl;
             cin.clear();
             std::string dummy;
             cin >> dummy; // Read the left invalid input
        }
        else {
           break;
        }
    }
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • I tried using this and for some reason it still goes infinitely when I enter something other than a double. – Suds2 Apr 26 '15 at 20:09
  • @vsoftco Yes, THX for pointing out. I've chosen to read a dummy string up to the next whitespace/return. – πάντα ῥεῖ Apr 26 '15 at 20:13
  • Ok it works now. I don't understand the std: part and the cin >> dummy. Could one of you explain what that means to me? – Suds2 Apr 26 '15 at 20:15
  • @Suds2 The `std::` part explicitly specifies `string` being used from the `std` namespace. The `cin >> dummy;` statement reads up any invalid characters left at the input stream. – πάντα ῥεῖ Apr 26 '15 at 20:19
  • @Suds2 you may find this link helpful: http://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input – vsoftco Apr 26 '15 at 20:19
  • Also instead of using cin >> dummy I used getline(cin, dummy) so that when someone inputted something with spaces it would prompt them only once instead of prompting them however many words they inputted. – Suds2 Apr 26 '15 at 20:21
2

You need to clear the stream's error flags, otherwise you keep looping, since no more other reads are performed when the stream is in a bad state, and radius keeps its value before the loop. You need to do the following (must #include <limits>):

if(!(cin >> radius)) // we didn't read a number, cin has a "bad" state
{
    cin.clear(); // clear the error flags
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // ignore the rest
    continue;
}
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Thank you! What does the "!" mean? I'm new to c++. – Suds2 Apr 26 '15 at 20:03
  • @Suds2 means `not`, i.e. negation. `cin >> radius` returns a stream, which is convertible to `bool`. Whenever the read operation is successful, the conversion results in `true`, otherwise is `false`. So the `if` is executed whenever `cin >> radius` is converted to `false`, e.g. bad read. – vsoftco Apr 26 '15 at 20:05