从标准输入中捕获字符而无需等待按下回车键

新手上路,请多包涵

我永远不记得我是如何做到这一点的,因为它对我来说很少出现。但是在 C 或 C++ 中,从标准输入读取字符而不等待换行符(按回车键)的最佳方法是什么。

理想情况下,它不会将输入字符回显到屏幕上。我只想在不影响控制台屏幕的情况下捕获击键。

原文由 Adam 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 913
2 个回答

这在纯 C++ 中以可移植的方式是不可能的,因为它过多地依赖于可能与 stdin 连接的终端(它们通常是行缓冲的)。但是,您可以为此使用库:

  1. conio 可用于 Windows 编译器。使用 _getch() 函数为您提供一个字符,而无需等待 Enter 键。我不是经常使用 Windows 开发人员,但我见过我的同学只是包含 <conio.h> 并使用它。参见 conio.h 维基百科。它列出了 getch() ,它在 Visual C++ 中被声明为已弃用。

  2. 可用于 Linux 的诅咒。兼容的 curses 实现也可用于 Windows。它还有一个 getch() 功能。 (尝试 man getch 查看其手册页)。参见维基百科上的 诅咒

如果您的目标是跨平台兼容性,我建议您使用 curses。也就是说,我确信您可以使用某些功能来关闭线路缓冲(我相信这称为“原始模式”,而不是“熟模式” - 查看 man stty )。如果我没记错的话,Curses 会以便携的方式为你处理。

原文由 Johannes Schaub - litb 发布,翻译遵循 CC BY-SA 4.0 许可协议

我遇到了同样的问题。这是使用带有 if(GetKeyState(keycode) & bitANDcompare){}; 的 cygwin g++ 的 Windows 控制台的小解决方案。

 #include <windows.h>
#include <fstream>
#include <iostream>

using namespace std;
void clear() {
    COORD topLeft  = { 0, 0 };
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    DWORD written;

    GetConsoleScreenBufferInfo(console, &screen);
    FillConsoleOutputCharacterA(
        console, ' ', screen.dwSize.X * screen.dwSize.Y, topLeft, &written
    );
    FillConsoleOutputAttribute(
        console, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
        screen.dwSize.X * screen.dwSize.Y, topLeft, &written
    );
    SetConsoleCursorPosition(console, topLeft);
}

class Keyclick{
    private:
    int key;
    char id;
    public:
    bool keydown = false;
    Keyclick(int key1, char id1){
        key=key1;
        id=id1;
    };
    void watch(){
        if(keydown==false){
            if(GetKeyState(key) & 0x8000 ){
                cout << id;
                cout << "  pressed.\r\n";
                keydown = true;
            }
        }
        if(keydown == true){
            if(!(GetKeyState(key) & 0x8000)) {
                cout << "released!!!!!!!!!!\r\n";
                keydown = false;
                clear();
            }
        }
    };
};

int main()
{
    bool primaryloop =true;
    Keyclick keysp(VK_SPACE,'S');
    Keyclick keyw(0x57,'w');
    Keyclick keya(0x41,'a');
    Keyclick keys(0x53,'s');
    Keyclick keyd(0x44,'d');
    Keyclick keyesc(VK_ESCAPE,'E');

    while(primaryloop){
        keysp.watch();
        keyw.watch();
        keya.watch();
        keys.watch();
        keyd.watch();
        keyesc.watch();

        if(keyesc.keydown){
            primaryloop=false;
        };
    }
    return 0;
}

https://github.com/wark77/windows_console_keypoller/blob/main/getkeystate_SOLUTION01.cpp

原文由 wark77 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题