while loop bug

I wrote a program which included a while loop to test the validity of a user-input choice (the "row" int variable), which should be at least 1.

It works as expected, provided the user does input an integer value.

If the user inputs a non-int value greater than 1, this is truncated to an int value and is processed as normal. I am happy for this sort of error to go unnoticed.

The problem is when a non-int value less than 1 is input, eg -0.5
I expected this to trigger the while loop, display the error message, wait for the user to input a new row value and try again.

Instead, the while loop is triggered, but the program does not wait for another value, instead going in an infinite loop printing the error message each time.

Can anyone explain in simple terms why it is doing this, and is there a non-highly technical fix for this weakness? (I am just a beginner!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// while issue test .cc
//
// testing problems with while loop
//
// Author: RJB
// Date: 17th Feb 2012
// Platform: Dev-C++, Windows XP

#include <iostream>

using namespace std;

int main ()
{
   int row; // Should be greate or equal to 1
   
   cout << "Enter number of rows" << endl ;
   cin >> row ;
   
   while (row < 1)
   {
         cout << "Error - number must be greater than or equal to 1. Try again"
              << endl ;
         cin >> row ;
   }
   
   cout << "success" << endl ;
    
    system("PAUSE");
    return 0;
}
Maybe you should declare row as a double.
Last edited on
Can anyone explain in simple terms why it is doing this

http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.2

and is there a non-highly technical fix for this weakness?

http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <limits>
.
.
.
  while (row < 1)
   {
         cin.clear();
         
         cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
         cout << "Error - number must be greater than or equal to 1. Try again"
              << endl ;
         cin >> row ;
   }
Last edited on
Perfect, thanks very much
I can't get as technical as some users here undoubtedly can.

The issue is that cin is attempting to extract a float to an integer, which causes the issue. In the case of anything greater then 1, you are extracting the integer component, hit the decimal, and it stops reading anything after that, but still leaves everything that hasn't been read in the buffer. The next time you try to read from cin, it's still there, so it checks the decimal. At that point, it tries to read a decimal into an int, and completly fails. When the integer component is greater then 1, you do not enter the while loop, and therefore do not use cin again, so you don't get erroneous behavior caused by the failed cin. It has failed tho, any attempt to use it again will fail, like you see in the loop.

You can check this by adding 2 extra lines, cout << cin.good() << endl ; to line 19 and cout << cin.good() << endl ; to line 30.

With those 2 additions, entering 1.5 twice in a row will later display on line 30 a 0, which is false, signifying cin is in a fail state.

Edit: Damnit Jim, I'm a programmer, not a speed typer
Last edited on
Topic archived. No new replies allowed.