Search code examples
c++conditional-statements

C++ All Int are valid for the if statement | if(choice == 1)


I've got some probably simple questions:

  1. why is every Integer accepted as a valid input in the if statement

  2. and why is the code following the if statement not being executed

#include <iostream>
#include <limits>

int main(){
    int choice;
    
    std::cout << "Enter the number 1" <<'\n';

    while (!(std::cin >> choice)){
        if(choice == 1) {
            std::cout << "good" << '\n';
            break;
        }
        else{
            std::cout << "bad" << '\n';
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "enter the number 1!"<< '\n';
         }
    }
    return 0;
}

Solution

  • The enclosing while ensures that the loop is only entered if the input is not a valid integer. The code inside the body of the while appears to mix this up. The if condition assumes the input is valid enough to be tested for 1-ness. This will ALMOST work with modern C++, since C++11, because choice will be set to 0, and can never be 1 inside the loop. In older C++ Standard versions, all bets are off. If it's not 1, the program clears the bad input and tries again. But once the user inputs a valid integer, the loop is never entered and the valid input will not be tested for 1-ness.

    This is a case where splitting things up with an extra function

    int get_int(std::istream & in)
    {
        int choice;
        while (!(in >> choice)) // stau in the loop until the user provides a good value
        {
            std::cout << "bad" << '\n';
            in.clear();
            in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "enter the number 1!"<< '\n';
        }
        return choice; // return the good value
    }
    

    makes the code dead easy to write. The above function will not exit until the user inputs a valid int. Then the main function can be a simple loop calling get_int and checking for 1-ness.

    int main(){
        std::cout << "Enter the number 1" <<'\n';
    
        while (get_int(std::cin) != 1){
            std::cout << "bad" << '\n';
            std::cout << "enter the number 1!"<< '\n';
        }
        std::cout << "good" << '\n';
    }
    

    Note that this is easy, but a little gross. See how many times we repeat std::cout << "enter the number 1!"<< '\n'? A bit more work and you can remove this repetition, but the code will be more complicated. Repetition makes code harder to maintain, but more complicated code is also more difficult to maintain. I see it as a matter of personal opinion which is better in this case.