【问题标题】:C++ loop until keystrokeC ++循环直到击键
【发布时间】:2011-08-18 10:04:29
【问题描述】:

如果我想循环直到击键,有一个非常好的 Windows 解决方案:

while(!kbhit()){ 
    //...
}

但这既不是 ISO 功能,也不适用于除 MS Win 之外的其他操作系统。我找到了其他跨平台解决方案,但它们非常混乱和臃肿 - 没有其他简单方法来管理它吗?

【问题讨论】:

  • 键盘本质上是一个外部设备,因此访问它会因系统而异...
  • Ncurses 是一个很棒的库,可以很好地替代<conio.h>
  • 请注意它来自conio lib。

标签: c++ loops cross-platform iso kbhit


【解决方案1】:

不,C++ 标准没有定义像“键盘”和“击键”这样的概念,因为并非所有系统都有这样的东西。使用一个可移植的库,也许ncurses 应该有什么。

【讨论】:

  • 当然这是使用 ncurses 的更好方法。查询不同操作系统的支持。
  • 根据我的经验,使用“便携式库”会将您带入一个黑暗的兔子洞。通常它们在某种意义上写得不好,它们试图使所有操作系统看起来像作者最喜欢/最知名的操作系统。结果,他们充其量只能为作者喜欢的那个操作系统生成最佳的东西。相反,编写一个抽象(带有函数原型的标头)。对于 N 个目标系统,编写 N 个 .c/c++ 文件,以最佳方式实现该功能。然后,只需链接到相应的实现。
  • @BitTickler:这就是我通常做的事情,但后来我又得到了另一个便携式库来做 X...:D
【解决方案2】:

您可以将下一版本的 kbhit() 用于 *nix 操作系统:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

【讨论】:

  • 好的,这行得通,但这不是 light 版本,并且比原来的 kbhit() 长得多...但是谢谢 - 听起来是迄今为止最好的解决方案.
  • 您可以尝试优化它...但最好使用跨平台决策。所以如果你是完美主义者,请不要使用 kbhit()。
猜你喜欢
  • 2020-05-17
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 2021-11-12
相关资源
最近更新 更多