_getch(), Esc key and the Windows console's behaviour

48 Views Asked by At

Нello!

As part of my current project, I have recently been working on a quick console prompt for entering a parameter, and ultimately came up with the following:

#include <iostream>
#include <string>
#include <conio.h>

static void parPrompt(const char*, std::string&);

int wmain(int argc, wchar_t* argv[])
{
    std::string par1, par2;

    parPrompt("Please enter the value for string parameter 1", par1);
    parPrompt("Please enter the value for string parameter 2", par1);
    std::cout << "Please press any key to exit";
    _getch();
}

static void parPrompt(const char* msg, std::string& parVal)
{
    std::cout << msg << " (Esc to skip):\n";

    char key = '\0';
    std::string line;

    while (true)
    {
        key = _getwche();
        switch (key)
        {
        case '\x1b':
        {
            std::cout << '~';
            if (!line.length())
            {
                std::cout << "Skipping the parameter...\n";
                break;
            }

            while (line.length())
            {
                std::cout << "\b \b";
                line.erase(line.length() - 1, 1);
            }
            continue;
        }

        case '\b':
        {
            if (line.length())
            {
                std::cout << " \b";
                line.erase(line.length() - 1, 1);
            }
            continue;
        }

        case '\r':
        case '\n':
        {
            std::cout << line << '\n';
            parVal = line;
            break;
        }

        default:
        {
            line += key;
            continue;
        }
        }
        break;
    }
}

While working on this, I encountered a particularly curious behaviour in the case when the Esc button is pushed, and as we will see in a second, the line std::cout << '~'; is there exactly to address it. Specifically, after Esc the next character for some reason is gobbled up, so that if I were to print:Skipping the parameter..., - without std::cout << '~'; (which is what the code was initially), only kipping the parameter... shows up.

Hence, my response to this was to print a character before the next message, so that gobbling up is in effect neutralised, and lines to follow appear intact. In the process I discovered that not every character can be used to that end: checking with the ASCII table, I have found out that only a character with the code of 0x30 and above (from '0' onwards) does the trick (and so I chose '~' for its code's being 0x7e - as well as some vague aesthetic reason).

In light of the above, I was wondering if could put forward the following question: why is it that pressing the Esc button causes this gobbling behaviour, and why is it that specifically a character from '0' onwards can be used to handle it?

0

There are 0 best solutions below