Home > Enterprise >  how do you define an exact case constant with a switch statement in c
how do you define an exact case constant with a switch statement in c

Time:02-22

I'm learning C and I don't fully understand how case works in switch statements. I have the following code:

bool accept3() {

    int tries = 1;

    while (tries<4) {
        std::cout<<"Do you want to proceed (y or n)?\n";
        char answer = 0;
        std::cin>>answer;

        switch(answer) {
        case 'y':
            return true;
        case 'n':
            return false;
        default:
            std::cout<<"Sorry, but I don't understand that.\n";
            tries   ;
        }
    }
    std::cout << "I'll take that as a no.\n";
    return false;
}

int main()
{
    //accept();
    //accept2();
    accept3();
}

It works as expected when you input, 'y', 'n', or any other single character that does not meet the two defined cases.

When you input any string of characters that begins with n, it still takes that as the 'n' case. Why does it do this? How can I make this more exact, so that it ONLY accepts 'n' and not 'no', 'no way' or any other string beginning with 'n'.

Thank you!

CodePudding user response:

This is tricky because if you input text with spaces into the terminal, like "d d d y", then you'll see the loop trigger 4 times in a row because "cin >> answer" breaks the line into separate inputs (this is called tokenization).

Here's code demonstrating how to properly parse an entire line of input as one menu command:

#include <iostream>
#include <string>

bool accept3() {

    int tries = 1;

    while (tries < 4) {
        std::cout << "Do you want to proceed (y or n)?\n";
        std::string answerStr;
        std::getline(std::cin, answerStr);
        
        char answer = '\0';
        if (answerStr.size() == 1) {
            answer = answerStr[0];
        }

        switch (answer) {
        case 'y':
            return true;
        case 'n':
            return false;
        default:
            std::cout << "Sorry, but I don't understand that.\n";
            tries  ;
        }
    }
    std::cout << "I'll take that as a no.\n";
    return false;
}

int main()
{
    //accept();
    //accept2();
    accept3();
}

CodePudding user response:

When you input any string of characters that begins with n, it still takes that as the 'n' case. Why does it do this?

Because you are asking cin to read a single char, so that is what it does. operator>>(char&) ignores leading whitespace, if any, and then reads 1 char. Any subsequent characters, if any, are left in the input buffer for later reads.

How can I make this more exact, so that it ONLY accepts 'n' and not 'no', 'no way' or any other string beginning with 'n'.

Use cin.getline() or std::getline() instead, and then compare the entire line, eg:

bool accept3() {

    int tries = 1;
    std::string answer;

    do {
        std::cout << "Do you want to proceed (y or n)?\n";
        std::getline(std::cin >> std::ws, answer);

        if (answer == "y")
            return true;
        if (answer == "n")
            return false;

        std::cout << "Sorry, but I don't understand that.\n";
          tries;
    }
    while (tries < 4);

    std::cout << "I'll take that as a no.\n";
    return false;
}
  •  Tags:  
  • c
  • Related