使用 std::cin 时如何限制可见的用户输入?

How to limit visible user input when using std::cin?

我正在寻找一种使用 std::cin 来限制可见用户输入的方法。

#include <iostream>
int main()
{
   std::cout << "Enter your planet:\n";
   string planet;
   std::cin >> planet; // During the prompt, only "accept" x characters
 }

如果用户在按回车键之前输入 earth 或任何其他超过 4 个字符的单词,他们会看到什么:

Enter your planet:
eart

这是假设字符限制为 4,请注意缺少 'h'。一旦超出字符限制,控制台将不再显示任何其他字符。这是在您按下回车键之前。

有点像在输入框中输入密码字段,但它只允许 5 个字符,因此输入任何其他字符都不会被注意到

更好的类比是 HTML 中文本输入的 maxlength 属性。

无法移植,因为 OS 控制台不是 C++ 标准的一部分。在 windows 中,您可以使用 <windows.h> header - 它提供控制台句柄等,但由于您没有指定您正在使用的 OS,因此发布没有意义windows-only 代码在这里(因为它可能无法满足您的需求)。


编辑:

这是(不完美的)代码,它将限制用户的可见输入:

#include <iostream>
#include <windows.h>
#include <conio.h>
int main()
{
    COORD last_pos;
    CONSOLE_SCREEN_BUFFER_INFO info;
    std::string input;
    int keystroke;
    int max_input = 10;
    int input_len = 0;
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

    std::cout << "Input (max 10) characters, press ENTER to prompt:" << std::endl;

    GetConsoleScreenBufferInfo(handle, &info);
    last_pos = info.dwCursorPosition;

    while(true)
    {
        if(kbhit())
        {
            keystroke = _getch();
            //declare what characters you allow in input (here: a-z, A-Z, 0-9, space)
            if(std::isalnum(keystroke) || keystroke == ' ') 
            {
                if(input_len + 1 > max_input)
                    continue;

                ++input_len;

                std::cout << char(keystroke);
                input += char(keystroke);

                GetConsoleScreenBufferInfo(handle, &info);
                last_pos = info.dwCursorPosition;
            }
            else if(keystroke == 8) //backspace
            {
                if(input_len - 1 >= 0)
                {
                    --input_len;
                    input.pop_back();

                    COORD back_pos {short(last_pos.X-1), last_pos.Y};

                    SetConsoleCursorPosition(handle, back_pos);
                    std::cout << ' ';
                    SetConsoleCursorPosition(handle, back_pos);

                    GetConsoleScreenBufferInfo(handle, &info);
                    last_pos = info.dwCursorPosition;
                }
            }
            else if(keystroke == 13) //enter
            {
                std::cout << std::endl;
                break;
            }
        }
    }

    std::cout << "You entered: " << std::endl
              << input << std::endl; 
}

经过几天的试验,我发现了另一个似乎很容易掌握的解决方案,因为它有点初学者水平,不需要任何 windows 编程知识。

注意: conio.h 库函数 _getch() 可以很容易地替换为 getchar() 函数;

我并不是说以前的答案不好,但这个解决方案有点针对只有 c++

基础知识的初学者
char ch;
string temp;
ch = _getch();
while(ch != 13)// Character representing enter
{
    if(ch == '\b'){ //check for backspace character
       if(temp.size() > 0) // check if string can still be reduced with pop_back() to avoid errors
       {
          cout << "\b \b"; //
          temp.pop_back(); // remove last character
        }
     }
    else if((temp.size() > 0)  || !isalpha(ch))// checks for limit, in this case limit is one
    {                                         //character and also optional checks if it is an alphabet
        cout << '\a'; // for a really annoying sound that tells you know this is wrong
    }else {
        temp.push_back(ch); // pushing ch into temp
        cout << ch; // display entered character on screen
    }
    ch = _getch();
}

这可能需要一些调整,因为它绝对不完美,但我认为它很容易理解,至少我希望如此