Ausghostdog
Ausghostdog

Reputation: 178

loop function until meets correct input

I am trying to get my code to keep looping until the correct input is entered, at present the code will compile and run but if an int is entered that is outside the allowed range it will simply return the error message and end, I am trying to find a way to clear the user input and request input again until a correct value is entered.

I have tried cin.clear and also returns but they seem not to work with functions or I simply do not understand how to implement them

#include <iostream>
#include <string>

using namespace std;


void get_int_ref(int& n);      

int main() {

    int n = 0; 
    get_int_ref(n); 

    return 0;
} 

void get_int_ref(int& n) {      
     cout<< "Please enter an integer\n"; 
     cin>>n;   
     if( n > 4000 )

        {
            cout << "Error enter a number n: 0 < n < 4000: \n" 

        }

     else if (n < 0)
        {
            cout << "Error enter a number n: 0 < n < 4000: \n"; 

        }
     else
        {
            cout<< n <<"\n";
        }

 }              

Upvotes: 0

Views: 205

Answers (5)

neshkeev
neshkeev

Reputation: 6476

Simply use a loop, for example, like this:

int main()
{
    int n = 0;
    while (1)
    {
        cout << "Enter a number n: 0 < n < 4000: \n"
        cin >> n;
        if (is_entered_value_valid(n)) break;
    }
    return 0;
}

bool is_entered_value_valid(const int& n)
{
    bool valid = true;
    if( (n > 4000) || (n < 0) )
    {
        cout << "Error enter a number n: 0 < n < 4000: \n"
        valid = false;
    }
    return valid;
}

As fairly @MikeCAT noted in the commentary block users might not always enter correct input. They might enter characters as well, like FooBar. Then this program gets existed with a error. You might need to add more complex input procedures with verification of the user's input. Let me know, If you need one.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206567

Separate the function into two functions:

  1. Get input.
  2. Check whether the input is valid.

Call them in a while loop from main.

 #include <iostream>
 #include <string>
 #include <limits>  // Needed for numeric_limits

 using namespace std;

 bool is_input_valid(int n);
 int get_input();      

 int main() {

     int n = get_input(); 
     while ( !(is_input_valid(n)) )
     {
        n = get_input();
     }

     return 0;
 } 

 int get_input() {      
    int n;
    cout << "Error enter a number between 0 and 4000: \n" 
    cin >> n; 

    // If there was a problem reading the input, clear the input stream
    // and try again.
    if ( !cin )
    {
       cin.clear();
       cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
       return get_input();
    }

    return n;
 }

 bool is_input_valid(int n)
 {
    return ( n >= 0 && n <= 4000 );
 }

Upvotes: 0

MikeCAT
MikeCAT

Reputation: 75062

  1. Read the input as string.
  2. Check if it is a correct input.
  3. If not, ask the user again.

example implementation:

#include <sstream> // for using std::stringstream

void get_int_ref(int& n) {
    // you shouldn't repeat writing the same message
    static const char* message = "Error enter a number n: 0 < n < 4000: \n";

    for(;;) // infinite loop
    {
        cout<< "Please enter an integer\n";
        std::string inp;
        if( !(cin>>inp) ) // failed to read a string
        {
            cout << "Input error\n";
            n = -1;
            break; // exit from the loop
        }
        std::stringstream ss;
        ss << inp;
        if( !(ss >> n) ) // what is read is not an integer
        {
            cout << message;
        }
        else if( n >= 4000 ) // correct condition according to the message
        {
            cout << message;
        }
        else if (n <= 0) // correct condition according to the message
        {
            cout << message;
        }
        else
        {
            cout << n << "\n";
            break; // exit from the loop
        }
    }
}

or the checking part can be more simple:

#include <sstream> // for using std::stringstream

void get_int_ref(int& n) {
    for(;;) // infinite loop
    {
        cout<< "Please enter an integer\n";
        std::string inp;
        if( !(cin>>inp )) // failed to read a string
        {
            cout << "Input error\n";
            n = -1;
            break; // exit from the loop
        }
        std::stringstream ss;
        ss << inp;
        if( !(ss >> n) || n >= 4000 || n <= 0)
        {
            cout << "Error enter a number n: 0 < n < 4000: \n";
        }
        else
        {
            cout << n << "\n";
            break; // exit from the loop
        }
    }
}

Upvotes: 3

Mr. Perfectionist
Mr. Perfectionist

Reputation: 2746

You can do it recursively.

void get_int_ref(int& n)
{
    cout<< "Please enter an integer\n";
    cin>>n;
    if( n > 4000 )
    {
        cout << "Error enter a number n: 0 < n < 4000: \n";
        get_int_ref(n);
    }

    else if (n < 0)
    {
        cout << "Error enter a number n: 0 < n < 4000: \n";
        get_int_ref(n);
    }
    else
    {
        cout<< n <<"\n";
        return;
    }

}

Upvotes: 0

tdao
tdao

Reputation: 17678

Can't you use a loop and break when detecting a correct input?

 while( true )
 {
     cout<< "Please enter an integer\n"; 
     cin>>n;   
     if( ( n > 4000 ) || ( n < 0 ) )
     {
            cout << "Error enter a number n: 0 < n < 4000: \n";
     }
     else
     {
            cout<< n <<"\n";
            break;
     }
}

Upvotes: 0

Related Questions