【问题标题】:portable alternative to kbhit() and getch() and system("cls")kbhit() 和 getch() 和 system("cls") 的便携式替代品
【发布时间】:2015-12-10 01:47:25
【问题描述】:

我需要一种以可移植方式使用 kbhit 和 getch 功能的方法。我目前正在开发一个简单的 ascii 游戏,我需要检测是否按下了某个键。如果是,我需要阅读它,如果不是,我需要继续而不等待输入。我宁愿不附和它,但我不会对此挑剔。我认为 kbhit 和 getch 对此非常有用,但我只被允许使用完全可移植的代码(至少是用于 linux、mac 和 PC 的代码,但我不会想到很多其他操作系统)。据我了解,termios、curses 和 conio 库并没有在我需要的所有三个操作系统上完全实现。我不知所措。我发现的每个解决方案都使用不可移植的代码。有没有办法我自己可以为此编写可移植的函数?我目前包括 stdio.h、stdlib.h 和 time.h。我还需要一种便携式方式来清除屏幕,因为我目前正在使用 system("cls") 和 system("clear") 每次我更改操作系统时也必须更改它们,或者是我可以做的一种方式if-else 并检测代码正在运行的操作系统以在这两个语句之间切换。下面是一段具有这些功能的代码:

    char key = ' ';
    while(1)
    {
        system("cls");
        if (_kbhit())
        {
            key =_getch();
            printf("output: %c", key);
        }    
        else
            printf("output:");
    }

这基本上是我在代码中需要的功能,但我想不出一种可移植的方式来做到这一点,而且我的老师要求代码在使用标准 c 和标准库的 Linux、mac 和 pc 上工作。请帮忙!请不要使用 c++,我们使用的是 c。

编辑:我不认为 ncurses 不是我想要的。有人建议我在编译时使用#ifdef 来实现这些。我喜欢这个解决方案,但我需要一些帮助来了解如何在 linux 和 mac 上执行此操作,因为我只能使用当前设置在 windows 上进行测试。希望我很快就会在我的另一台机器上运行 linux 进行测试,但是 OSX 的价格很高,所以我将不胜感激。这是当前代码:

 //libraries
#include <stdio.h>      //used for i/o
#include <stdlib.h>     //used for clearing the screen
#include <time.h>       //used to get time for random number generator

//check OS and include necessary libraries
#ifdef _WIN32
    //code for Windows (32-bit and 64-bit, this part is common)
    #include <conio.h>
    #define CLEARSCREEN system("cls")
    #define CHECKKEY _kbhit()
    #define NBGETCHAR getch()

#elif __APPLE__
    //code for mac
    #define CLEARSCREEN system("clear")
    #define CHECKKEY 
    #define NBGETCHAR 

#elif __linux__
    //code for linux
    #define CLEARSCREEN system("clear")
    #define CHECKKEY 
    #define NBGETCHAR 

#else
#   error "Unknown compiler"
#endif

int main()
{
    char key = ' ';
    while(1)
    {
        CLEARSCREEN;
        if (CHECKKEY)
        {
            key=NBGETCHAR;
            printf("output: %c", key);
        }    
        else
            printf("output:");
    }
}

【问题讨论】:

  • 一种解决方案是使用#ifdef 为操作系统选择(在编译时)正确的代码。可移植代码并不意味着“编译一次,到处运行”。这意味着在每个操作系统上编译,只需要尽可能多的操作系统依赖项。
  • 没有便携的方法可以做到这一点。最接近您的是某种为您处理可移植性问题的第三方库。诅咒可能是最接近这样做的。否则,您必须编写自己的 clear()、kbhit() 和 getch() 函数,并为每个操作系统使用不同的版本。
  • 为什么没有便携的方法来做到这一点?
  • 因为类 unix 操作系统(Mac OS X、GNU/Linux 等)和 Microsoft Windows NT 完全不同。在 Windows 中,有 API 可以用控制台窗口做一些有趣的事情,而在 unixes 中,使用 curses 来读取和写入由物理终端引入的 神奇字节序列,例如VT100 并且仍然被终端仿真器使用。 / 历史就是为什么没有可移植的方式来做到这一点。

标签: c portability getch kbhit


【解决方案1】:

您应该查看可移植的ncurses 库。除了在终端中绘制的许多其他工具外,它还提供了一个keyboard interface,其中包括一个getch()函数。

【讨论】:

  • 这不是解决方案。 ncurses 接管您的屏幕,并且与现有的控制台程序不兼容。一旦你去诅咒你必须将你的整个程序转换为诅咒以保持一致。 ncurses 还会清除您的屏幕,这通常会吓到习惯于仅运行仅滚动的程序的用户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
相关资源
最近更新 更多