Home > Back-end >  C non integer is acting like 0
C non integer is acting like 0

Time:04-27

I have been learning C and I have made a simple console app. but when I made an if statement to check if the input is an integer, the non-integer characters seem to be equal to 0 so when I input a non-integer character it acts like I inputted a 0. I am trying to make it so when I input 0 the app closes but the problem is that when I input a character the app closes also.

I can try to explain more with you cod below.

int main()
{
    // Use > SetConsoleTextAttribute(h,13); < for text color
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);

    int input;

    std::cout << "Pleas enter (1 or 2).\n";

    while(true)
    {
        // Set coler to default
        SetConsoleTextAttribute(h,7);
        std::cin >> input;

        if(input == 0)
        {
            return(0);  "<--- this is where I am trying to close the app."
        }

        if(input == 1)
        {
            // Set coler to green
            SetConsoleTextAttribute(h,10);
            std::cout << "hi\n";
        }

        if(input == 2)
        {
            // Set coler to green
            SetConsoleTextAttribute(h,10);
            std::cout << "bye\n";
        }

        // Check if input is to an integer
        if(! std::cin >> input)       "<--- this is where I am checking if input is to an integer"
        {
        // Set coler to red
        SetConsoleTextAttribute(h,4);
        // Explain the error
        std::cout << "Error: input is not a number.\n";
        // Clear the previous input
        std::cin.clear();
        // Discard previous input
        std::cin.ignore(123, '\n');
        continue;
        }

        // Check if input is to large
        if(input > 2)
        {
            // Set coler to red
            SetConsoleTextAttribute(h,4);
            std::cout << "Error: input to large.\n";
            continue;
        }

        // Check if input is to small
        if(input < 0)
        {
            // Set coler to red
            SetConsoleTextAttribute(h,4);
            std::cout << "Error: input to small.\n";
            continue;
        }

    }

    return 0;
}

CodePudding user response:

This operation

std::cin >> input;

has a side-effect. Having the same code in your program multiple times isn't the same as doing it just once.

In particular,

if(! std::cin >> input)

has no hope of doing what you wanted, because

  1. If the first data input failed, you already exited the program and never reached this.

  2. If the first data input succeeded, this if isn't checking the status following the first data input, it's going to try to read a second time from cin.

Take your error handling and replace the first std::cin >> input; don't just paste it down below.

CodePudding user response:

You're checking if input == 0 before you check if the input was successfully processed into an integer. Furthermore, note that std::cin >> input; followed by if(! std::cin >> input) will read from cin twice, not once.

When you enter input that would cause std::cin >> input to fail, the following happens, according to cppreference:

If extraction fails (e.g. if a letter was entered where a digit is expected), zero is written to value and failbit is set. For signed integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() (respectively) is written and failbit flag is set. For unsigned integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() is written and failbit flag is set.

So input == 0 will be true after you enter something like "cat" that cannot be converted to an int.

CodePudding user response:

You need to check if the read worked:

if (std::cin >> input) {

    if(input == 1)
    {
        // Set coler to green
        SetConsoleTextAttribute(h,10);
        std::cout << "hi\n";
    }

    // etc
}
else {
    // Input failed.
    return 0;
}
  • Related