【问题标题】:How to make the console print something by pressing a key like F2 or F3如何通过按 F2 或 F3 之类的键使控制台打印一些东西
【发布时间】:2020-05-30 23:24:15
【问题描述】:

更新!我想出了如何找到密钥并在我的代码中定义它们。问题是我不知道如何制作它,所以控制台打印选择,它让你有时间按下一个键。然后它被插入到根据按下的键打印当前枪的开关上。我也在使用 Windows 10。我还遇到了另一个问题,我希望它先打印出 Guns,然后要求输入(这部分工作正常),但它不仅打印附件,还打印出附件和人性化级别.

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


using namespace std;

#define KEY_F1 17
#define KEY_F2 18
#define KEY_F3 19
#define KEY_F4 20
#define KEY_F5 21
#define KEY_F6 22
#define KEY_F7 23
#define KEY_F8 24
#define KEY_F9 25
#define KEY_F10 26
#define KEY_F11 27
#define KEY_F12 28

#define KEY_N7 103
#define KEY_N8 104
#define KEY_N9 105


int main() {

    char gun;
    char att;
    char hum;

    char key = _getch();
    int value = key;

    cout << "" << endl;

    cout << "Developed by ! CaptaiN#9999" << endl;

    cout << "" << endl;

    cout << "Guns" << endl;

    cout << "" << endl;

    cout << "[F1]   AK" << endl;
    cout << "[F2]   MP5" << endl;
    cout << "[F3]   M2" << endl;
    cout << "[F4]   SAR" << endl;
    cout << "[F5]   Tommy" << endl;
    cout << "[F6]   Custom" << endl;
    cin >> gun;


    cout << "" << endl;

    cout << "Attachnments" << endl;

    cout << "" << endl;

    cout << "[F7]   Holosight" << endl;
    cout << "[F8]   Simplesight" << endl;
    cout << "[F9]   Silencer" << endl;
    cout << "[F10]  8x Zoom Scope" << endl;
    cout << "[F11]  16x Zoom Scope" << endl;
    cout << "[F12]  No Attachment" << endl;
    cin >> att;

    cout << "" << endl;

    cout << "Humanize Levels" << endl;

    cout << "" << endl;

    cout << "[Numpad 7]  3 (HIGH)" << endl;
    cout << "[Numpad 8]  2 (MODERATE)" << endl;
    cout << "[Numpad 9]  1 (LOW)" << endl;
    cin >> hum;




    //system("CLS");

    while (value != KEY_X) {

        switch (_getch()) {

        case KEY_F1:
            cout << "Current Gun: AK" << endl;
            break;
        case KEY_F2:
            cout << "Current Gun: MP5" << endl;
            break;
        case KEY_F3:
            cout << "Current Gun: M2" << endl;
            break;
        case KEY_F4:
            cout << "Current Gun: SAR" << endl;
            break;
        case KEY_F5:
            cout << "Current Gun: Tommy" << endl;
            break;
        case KEY_F6:
            cout << "Current Gun: Custom" << endl;
            break;
        }

        switch (att) {

        case KEY_F7:
            cout << "Current Attachment: Holosight" << endl;
            break;
        case KEY_F8:
            cout << "Current Attachment: Simplesight" << endl;
            break;
        case KEY_F9:
            cout << "Current Attachment: Silencer" << endl;
            break;
        case KEY_F10:
            cout << "Current Attachment: 8x Zoom Scope" << endl;
            break;
        case KEY_F11:
            cout << "Current Attachment: 16x Zoom Scope" << endl;
            break;
        case KEY_F12:
            cout << "Current Attachment: None" << endl;
            break;
        }

        switch (hum) {

        case KEY_N7:
            cout << "Humanized Level: 3" << endl;
            break;
        case KEY_N8:
            cout << "Humanized Level: 2" << endl;
            break;
        case KEY_N9:
            cout << "Humanized Level: 1" << endl;
            break;
        }
    }
}

【问题讨论】:

  • 给我们看一些代码,
  • 如果您按A 之类的常用键(之后不按回车键),甚至没有一种标准方法可以让您的程序打印任何内容。对于此类事情,您将需要特定于平台的代码。有适用于大多数平台的库,例如 ncursespdcurses

标签: c++ windows input switch-statement


【解决方案1】:

我认为pm100 的回答是一种完全可以接受的方法,但是这种技术产生的代码会很脆弱并且依赖于平台(因为他提到没有标准表示)。

如果你觉得没问题,请使用他的答案。一种更便携的方法是使用终端控制库,最常见的是curses (它在技术上是一个 c 库仅供参考)。主要有两种实现方式:pdcurses 主要用于 Windows,ncurses 用于 Mac 和 Linux。我不会在这里进行设置,因为这主要取决于库,但如果你想让它跨平台,你可以使用 cmake 但这并不容易(因为你必须处理 pdcurses 和 ncurses分开)。

不管 curses 实现如何,捕获 F1-F12 键的最小示例如下:

#ifdef _WIN32
#include <pdcurses.h>
#else
#include <ncurses.h>
#endif

int main()
{
    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    while (true) {
        int ch = getch();
        if (ch >= KEY_F(1) && ch <= KEY_F(12)) {
            printw("F* key pressed\n");
        }
    }

    endwin();
    return 0;
}

有关该库的更多详细信息,我推荐this 编程指南。

作为旁注,您可能需要考虑使用类似 std::map 的方法将您的键映射到 std::string,因为它比使用 switch 语句更简洁。

【讨论】:

  • 除了“像 std::unordered_multimap 之类的东西”之外,这个容器在这里似乎是一个糟糕的选择。我会使用一个简单的 map.
  • 是的,你是对的,地图的多方面是完全不需要的,无序的性能提升可以忽略不计。我将编辑我的答案以反映这一点。谢谢你抓住我!
【解决方案2】:

功能键没有标准表示。因此,首先计算按下 Fn 时到达您的应用程序的字符。很可能它不止一个字符。

在 linux 上你可以做到

cat > fn.bin
od -tx2 fn.bin

这显示了 Fn 生成了哪些字符

【讨论】:

    【解决方案3】:

    好的,既然你的问题基本上已经改变了,我会提出一个新的答案来解决它。我看到你已经选择了特定于平台的选项。幸运的是,我也在使用 Windows 10,所以我仍然可以提供帮助。

    首先,我对您在定义中列出的键码有一些困难 - 我得到一个空字符 (0),然后是其他一些字符,例如 ; (59) 用于 F1 和 > (60) 用于 F2。对于 F11 和 F12,我得到了一组完全不同的字符(如您在我的代码中所见)。我不太确定为什么我们会得到不同的结果,也许编码有些奇怪?您介意说明您在哪里找到了 sn-p 中列出的字符代码吗?对于我的其余答案,我将只使用我得到的(抱歉,我不知道还能做什么)。

    这是实现我认为您想要的代码 - 它在代码的第一部分获取用户的初始“加载”。在主循环中,它允许您输入新武器,并且只打印之前选择的附件。我没有添加对数字键盘键的处理,但是如果您想这样做,技术应该是相同的。

    #include <iostream>
    #include <string>
    #include <conio.h>
    #include <array>
    #include <map>
    
    // define the parts for all F* keys
    using multipart_t = std::array<int, 2>;
    constexpr multipart_t KEY_F1 = { 0, 59 };
    constexpr multipart_t KEY_F2{ 0, 60 };
    constexpr multipart_t KEY_F3{ 0, 61 };
    constexpr multipart_t KEY_F4{ 0, 62 };
    constexpr multipart_t KEY_F5{ 0, 63 };
    constexpr multipart_t KEY_F6{ 0, 64 };
    constexpr multipart_t KEY_F7{ 0, 65 };
    constexpr multipart_t KEY_F8{ 0, 66 };
    constexpr multipart_t KEY_F9{ 0, 67 };
    constexpr multipart_t KEY_F10{ 0, 68 };
    constexpr multipart_t KEY_F11 = { 224, 133 };
    constexpr multipart_t KEY_F12 = { 224, 134 };
    
    // map those arrays to the corresponding ints
    const std::map<multipart_t, int> F_KEY_TO_INT{
        { KEY_F1, 1 },
        { KEY_F2, 2 },
        { KEY_F3, 3 },
        { KEY_F4, 4 },
        { KEY_F5, 5 },
        { KEY_F6, 6 },
        { KEY_F7, 7 },
        { KEY_F8, 8 },
        { KEY_F9, 9 },
        { KEY_F10, 10 },
        { KEY_F11, 11 },
        { KEY_F12, 12 }
    };
    
    // add a utility function that returns the pressed key as an int of 1-12 (for F1-F12 keys)
    int fGetch() {
        // TODO: add checking to check it actually is an F* key instead of just failing silently (REALLY BAD)
        multipart_t keys;
        keys[0] = _getch();
        keys[1] = _getch();
        return F_KEY_TO_INT.find(keys)->second;
    }
    
    int main() {
        std::cout << "" << '\n';
    
        std::cout << "Developed by ! CaptaiN#9999" << '\n';
    
        std::cout << "" << '\n';
    
        std::cout << "Guns" << '\n';
    
        std::cout << "" << '\n';
    
        std::cout << "[F1]   AK" << '\n';
        std::cout << "[F2]   MP5" << '\n';
        std::cout << "[F3]   M2" << '\n';
        std::cout << "[F4]   SAR" << '\n';
        std::cout << "[F5]   Tommy" << '\n';
        std::cout << "[F6]   Custom" << '\n';
        // TODO: valid character checking (for all 3)
        int gun(fGetch());
    
    
        std::cout << "" << '\n';
    
        std::cout << "Attachnments" << '\n';
    
        std::cout << "" << '\n';
    
        std::cout << "[F7]   Holosight" << '\n';
        std::cout << "[F8]   Simplesight" << '\n';
        std::cout << "[F9]   Silencer" << '\n';
        std::cout << "[F10]  8x Zoom Scope" << '\n';
        std::cout << "[F11]  16x Zoom Scope" << '\n';
        std::cout << "[F12]  No Attachment" << '\n';
        int att(fGetch());
    
        // I'll leave you to handle function keys, it should be basically the same
        /*std::cout << "" << '\n';
    
        std::cout << "Humanize Levels" << '\n';
    
        std::cout << "" << '\n';
    
        std::cout << "[Numpad 7]  3 (HIGH)" << '\n';
        std::cout << "[Numpad 8]  2 (MODERATE)" << '\n';
        std::cout << "[Numpad 9]  1 (LOW)" << '\n';
        std::cin >> hum;*/
    
        system("CLS");
    
        std::cout << "main loop start" << '\n';
        int value = 0;
        while (value != 'x') {
            value = fGetch();
    
            switch (value) {
            case 1:
                std::cout << "Current Gun: AK" << '\n';
                break;
            case 2:
                std::cout << "Current Gun: MP5" << '\n';
                break;
            case 3:
                std::cout << "Current Gun: M2" << '\n';
                break;
            case 4:
                std::cout << "Current Gun: SAR" << '\n';
                break;
            case 5:
                std::cout << "Current Gun: Tommy" << '\n';
                break;
            case 6:
                std::cout << "Current Gun: Custom" << '\n';
                break;
            }
    
            switch (att) {
    
            case 7:
                std::cout << "Current Attachment: Holosight" << '\n';
                break;
            case 8:
                std::cout << "Current Attachment: Simplesight" << '\n';
                break;
            case 9:
                std::cout << "Current Attachment: Silencer" << '\n';
                break;
            case 10:
                std::cout << "Current Attachment: 8x Zoom Scope" << '\n';
                break;
            case 1:
                std::cout << "Current Attachment: 16x Zoom Scope" << '\n';
                break;
            case 12:
                std::cout << "Current Attachment: None" << '\n';
                break;
            }
    
            // TODO
            /*switch (hum) {
    
            case KEY_N7:
                std::cout << "Humanized Level: 3" << '\n';
                break;
            case KEY_N8:
                std::cout << "Humanized Level: 2" << '\n';
                break;
            case KEY_N9:
                std::cout << "Humanized Level: 1" << '\n';
                break;
            }*/
        }
    }
    

    在代码中,我添加了一些地方供您改进(主要是检查用户在错误的时间输入了错误的键)。

    实际输入是通过将多个字符放入一个数组并使用映射将其映射到该 F1-F12 键的适当 int 来处理的。请注意,该功能目前几乎没有错误检查。

    【讨论】:

      猜你喜欢
      • 2022-10-07
      • 1970-01-01
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      • 1970-01-01
      相关资源
      最近更新 更多