Require the user to enter an integer

Part of the program I am working on requires the user to enter how many passengers will be in a carpool (2-6). The professor is obsessed with robustness. I've used a while loop to require the number to be at least 2 and no more than 6. If a higher or lower number is entered a message displays telling the user to choose a number in that range and won't let them proceed until they do. How do I add a second condition, which prevents them from entering say 2.2 passengers? Any other tips about line spacing or other aesthetics would be greatly appreciated. Our professor just doesn't care.

1
2
3
4
5
6
 cout << "\nCounting yourself how many people are in your carpool?" << endl;
    cin >> people;
    while (people < 2 || people > 6){
        cout << "\nThere must be at least 2 people and no more than 6. Try again: " << endl;
        cin >> people;
    }
Make people be of type double and change the conditional to:

(people < 2 || people > 6) && (int)people == people
Make people be of type double and change the conditional to:
Don't

How often do you have half a person in your car josue?

Actually it is undefined behavior if someone enters 2.2 if your variable people is an int.

You can however do something like this
1
2
3
4
5
6
while( !std::cin >> people ) //( or .fail its the same )
{
    cout << "That is an invalid input" << endl;
    cin.clear();
    cin.ignore( numeric_limits<streamsize>::max() , '\n' );
}


Edit actually they are both numbers but it should round 2.2 down to 2 anyways when you input it..
but this prevents someone entering say a or any other char/s.
Last edited on
Thank you for your quick replies. I'm in an accelerated class and just learned about loops yesterday. The only thing left for me to figure out is how to work it around or into the loop I already have.
giblit, that was just a little hack. If we want to get into correct software engineering practices, then a good way to achieve this would be the following:

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
#include <iostream>
#include <cstdlib>

bool is_integer(const std::string& s)
{
    if(s.empty() || ((!std::isdigit(s[0])) && (s[0] != '-') && (s[0] != '+')))
    {
        return false;
    }

    char* p;
    std::strtol(s.c_str(), &p, 10);

    return (*p == 0);
}

int main()
{
    std::string input;

    std::cout << "Counting yourself, how many input are in your carpool?" << std::endl;
    std::cin >> input;

    while (!is_integer(input) || std::atoi(input.c_str()) < 2 || std::atoi(input.c_str()) > 6)
    {
        std::cout << "Enter at least two and at most six people: " << std::endl;
        std::cin >> input;
    }

    return 0;
}

Also, your program does not work.
Last edited on
I can see that I asked a question with an answer that is still over my head. I was told by the tutor that professional programmers don't use "using namespace std;" so I get why your programs are so full of stds, but we haven't covered strings or atoi, so I'm guessing the professor probably won't mark me down in this case. I will experiment with your replies just do see what happens though.
> How do I add a second condition, which prevents them from entering say 2.2 passengers?
> but we haven't covered strings

If we can't use a string to validate the input, we need to perform a look ahead; ie. read an int and then read the next character.

std::cin >> integer_value ; reads an integer and leaves the next character (which does not form part of the integer) in the input buffer.

std::cin.get( char_value ) ; retrieves the next character (even if it is a white space). If that character is a white space (eg. newline), the user has entered just an integer; if not all the characters in input do not constitute just an integer.

Something like this:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <cctype>

int read_int( const char* prompt, int minv, int maxv )
{
    int value ;
    char delimiter ;

    std::cout << prompt << " (integer in [" << minv << ',' << maxv << "])? " ;

    // try to read an int, immediately followed by a white space character
    if( std::cin >> value && std::cin.get(delimiter) &&  std::isspace(delimiter) )
    {
        // the user did enter an integer value
        // if value is in with range, return it
        if( value >= minv && value <= maxv ) return value ;

        // if not, inform the user of the error and try again
        std::cout << value << " is out of range\n" ;
    }

    else
    {
        // the user did not enter an integer value
        // inform the user of the error
        std::cout << "input is not an integer\n" ;

        // clean up
        std::cin.clear() ; // clear failed state if any
        std::cin.ignore( 1000, '\n' ) ; // throw away any junk left in the input buffer

        // and try again
    }

    return read_int( prompt, minv, maxv ) ; // try again
}

int main()
{
    constexpr int MIN_PEOPLE = 2 ;
    constexpr int MAX_PEOPLE = 6 ;
    const char* prompt = "Counting yourself how many people are in your carpool" ;

    const int people = read_int( prompt, MIN_PEOPLE, MAX_PEOPLE ) ;

    std::cout << "there are " << people << " people in the car pool\n" ;
}
Topic archived. No new replies allowed.