Zack
Zack

Reputation: 11

Problems with Program flow

So I'm going to preface by saying this is my first post. I've hit a bit of a rut and can't find a simple answer that's working for me.

I'm so new I'm still on command line programs but here I want to create a program that will accept an int value from the user. I want to check and verify that it is in fact an integer value. If it is not I want the user to be told to input a correct integer value. If it is correct I want to move on. I want to continue to ask for proper input until the user gives me an integer value.

Here's what I have been attempting to do:

#include <iostream>

using namespace std;

int main()
{

   int n;

   do {

      if (isdigit(n)==false) {
         cout<<"Enter an integer number\n";
         cin>>n;
         continue;
      }
      else {
         cout<<"Good Job\n";
      }
   } while(isdigit(n)==false);

}

As you can probably guess this gives me an infinite loop. I cannot for the life of me get this to behave how I want it to.

Upvotes: 1

Views: 115

Answers (3)

R Sahu
R Sahu

Reputation: 206717

You are on the right track. The checks you are performing to determine an integer was successfully read is not correct. isdigit is meant to check whether a single character is a digit or not. The range of values for which isdigit returns true is ['0' - '9']. Expressed in integers, that range is [48 - 57]. It is not a valid use for your purpose.

Here's an updated version that should work:

#include <iostream>

using namespace std;

int main()
{

   int n;
   while ( true )
   {
      cout << "Enter an integer number\n";
      if ( cin >> n )
      {
         cout<<"Good Job\n";
         break;
      }
      else
      {
         // Clear the stream and ignore the rest of the line.
         cin.clear();
         cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      }
   } 
}

Upvotes: 3

ch41rmn
ch41rmn

Reputation: 121

There are several problems here.

  1. Firstly, as @jrd1 has linked, the way you cast cin>>n is incomplete. Your program's function appears to require some kind of validation, but cin fails if the input is not numeric (see the use of cin.fail() in integer input validation, how? and Integer validation for input). You must check if cin has failed, and refresh cin for the next round of input.

  2. One of your if statement and while statement is redundant, since n does not change between the evaluation of while and if on the subsequent loop.

  3. Since you must check if cin has failed, there is no need to additionally check isdigit(n). That is, if cin did not fail, then n must be a digit.

  4. Your continue statement is redundant. continue skips to the end of the loop, but this is not necessary since all the remaining code is in the else block, hence there is nothing to skip over. This is only useful if you want to skip any code after your if block (which your code doesn't have).

  5. Your intention with the else block appears to indicate a successful validation. You may consider using a break statement, which breaks the code execution out of the current loop.

Once you take into account of all of these, you will arrive at something like @R-Sahu's code.

This is an example that most closely resembles your code:

#include <iostream>

using namespace std;

int main() {

    int n;

    do {
        cout<<"Enter an integer number\n";
        cin>>n;

        if(cin.fail()) {
            cout << "Wrong Input" <<endl;
            cin.clear(); 
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
        } else {
            break;
        }

    } while (true);

    cout<<"Good Job\n"<<endl;

}

Here is another example that is "more" streamlined, and does not require break or continue statements (stylistic choices for better "readable" code by some programmers)

#include <iostream>

using namespace std;

int main() {

    int n;

    cout << "Enter an integer number\n" << endl;
    cin>>n;
    while ( cin.fail()){
            cout << "Wrong Input. Enter an integer number\n" <<endl;
            cin.clear(); 
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cin>>n;
    }

    cout<<"Good Job\n"<<endl;

}

EDIT: fixed a problem in the second example where ! cin>>n was not behaving as expected.

EDIT2: fixed a problem in the first example where isdigit was incorrectly applied. See R Sahu's explanation.

Upvotes: 2

Zack
Zack

Reputation: 11

Thanks for all your help guys, I was finally able to get the code to run using a slightly modified version of ch41rmn's suggestion. The "streamlined" version directly bypassed the while loop. And the second one didn't exit even if a correct int value was given. This is what I used:

#include <iostream>

using namespace std;

int main() {

    int n;

    do {
        cout<<"Enter an integer number\n";
        cin>>n;

        if(cin.fail()) {
            cout << "Wrong Input" <<endl;
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        else{
            break;
        }

    } while(isdigit(n)==false);

    cout<<"Good Job\n";

}

while this might be quite redundant, I'm happy the SOB runs.

THANKS!

Upvotes: 0

Related Questions