0

I am following C++ Programming language book and came upon code similar to one below:

bool acceptSwitchWithRetry()
{
    int tries = 0;
    while (tries < 4) {
        cout << "Do you want to proceed?" << endl;

        char answer = 0;
        cin >> answer;
        switch (answer) {
        case 'n':
            return false;
        case 'N':
            return false;
        case 'y':
            return true;
        case 'Y':
            return true;
        default:
            cout << "I didn't understand that please specify one of following 'n','N','y','Y'" << endl;
            ++tries;
        }
    }
    cout << "I will take that as no" << endl;
    return false;
}

The code works fine if user enters any single character but if multiple characters get entered ten they remain in cin and on next iteration of the loop it doesn't even ask user to enter a character but instead uses next character in the cin buffer.

When can be done to improve this code?

Thank you in advance.

I tried using string object and if,else statements instead but doesn't use switch-statement.

8
  • 2
    This function is not that well written, but if you just want to solve the issue of multiple characters then learn about cin.ignore(). Commented May 31 at 10:46
  • 1
    "Real" text-mode software with interactive prompts/inputs that's written in C or C++ won't be using cout directly, nor will the programmer concern themselves with any of the extremely tedious low-level work in a prompt+validate+proceed loop, not least because it's too easy for things to break because the user has some newfangled terminal or entering Unicode emojis, etc - the go-to for most people is something like ncurses.
    – Dai
    Commented May 31 at 10:47
  • Read a full line not a single character. Commented May 31 at 11:19
  • If the user enters for example Yaa, do you consider it a "yes" answer and discard the rest of the characters ("aa"), or do you require valid input to have only 1 character ? Please edit your question and clarify the required behavior.
    – wohlstad
    Commented May 31 at 12:11
  • FYI, if you use std::toupper() you can reduce your comparisons by half. See also std::tolower(). Commented May 31 at 14:59

1 Answer 1

-2

Generally provided code is totally ok. Of course, you may want to have 'if' statement, but switch will do the thing. The only change I would recommend is the following:

 switch (answer) {
    case 'n':
        [[fallthrough]] (after C++17)
    case 'N':
        return false;
    case 'y':
        [[fallthrough]] (after C++17)
    case 'Y':
        return true;
3
  • 4
    [[fallthrough]] isn't for that purpose. Consecutive cases with the same body can simply lie next to each other Grouping switch statement cases together?. So just remove the two redundant return false; and return true; in the 'n' and 'y' case
    – phuclv
    Commented May 31 at 10:43
  • I recommend using std::toupper() or std::tolower() to reduce the quantity of comparisons: answer = std::toupper(answer); return answer == 'Y'; Commented May 31 at 15:02
  • @ThomasMatthews it's clearly more readable. Not effective but nice and acceptable. But these functions already do more comparisons than this switch though, because they use some unspecified internal structure (which you can reassign by changing locale and character class) to convert lowercase into uppercase. Commented Jun 2 at 21:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.