为什么getch()在以很短的延迟调用halfdelay()后读取EOF?

时间:2018-06-15 12:24:27

标签: c ncurses

我正在使用 ncurses 进行体验,并且在使用halfdelay时出现小延迟时,我偶然发现了一些违反直觉的行为。

以下内容需要用户输入键盘。我不是只按下并释放按键,而是按下按键进行测试,以便它继续打印相应的字符(更确切地说,相应的int值)。这是我所拥有的剥离版本:

#include <ncurses.h>

int main() {
  int c = 0, d = 0, e = 0;

  initscr();
  cbreak();
  noecho();
  keypad(stdscr, TRUE);

  while ('q' != (c = getch())) {
    printw("c: %d\n", c);

    // Make sure that halfdelay returned OK. It should as the input is in the expected range ([1, 255])
    if ((d = halfdelay(1)) != OK) {
      printw("d: %d\n", d);
      return 0;
    }

    e = getch();

    printw("e: %d\n", e);
    cbreak();
  }

  endwin();
  return 0;
}

以下是我如何构建并运行它:

$ gcc -Wall -Wpedantic -lncurses file.c
$ a.out

运行时的输出(在键盘上按住a约1秒后):

c: 97
e: -1
c: 97
e: 97
c: 97
e: 97
c: 97
e: 97
c: 97
e: 97
c: 97
e: 97
c: 97
e: -1

问题 这个输出中来自-1 / EOF的位置是什么?我注意到通过增加延迟(在我的机器上从1到7)使EOF字符完全消失。我很想知道这个机制是什么原因。

1 个答案:

答案 0 :(得分:2)

TL;博士 如果输入速度太慢,则无法获得getch的密钥,但会获得EOF

长版:

根据ncurses手册,半延迟模式意味着输入功能会等到按下某个键或给定的超时间隔到期。 使用halfdelay(1),您不仅可以将输入模式设置为半延迟,还可以将此间隔设置为1/10秒。 这意味着如果您未在1/10内获得密钥,则无论如何都会返回该函数。

另一方面按住一个键可以创建多个按键。如果这些按键的速度太慢而无法适应半延迟时间间隔,则有时您按下按键会看到EOF

因此,如果您将间隔增加到按键间隔之外,则可以避免获得EOF

要验证这些数字,您可以尝试确定按住某个键的键重复率是多少。它可能不到每秒7次。