我在C中编写一个程序,它使用ncurses来检查是否按下了某个键。问题是有一个关键的重复延迟。
如果我在终端中按住键'a',则在重复输入'a'之前会有短暂的延迟。我希望能够知道它是否从实际按下它的位置被按下。
如何在终端中暂时将此延迟更改为等于0?我目前正在使用Mac OSX 10.10.5。
答案 0 :(得分:1)
使用ncurses(任何curses实现),您将使用getch
而不是getchar
。后者是C标准I / O输入功能。
有人建议 Create a function to check for key press in unix using ncurses ,其中包含一个值得一提的答案。它使用nodelay
来消除通常在getch
中为转义序列的连续字节花费的时间。在curses中,您总是在等待与否之间进行权衡,因为转义序列可能无法在一次read
操作中到达。这里显示的示例报告没有字符可用的情况,并在这种情况下暂停(休眠)一小段时间。
如果您只想查看读取的字符,可以消除该暂停(但会使您的程序占用大量CPU时间):
#include <ncurses.h>
int kbhit(void)
{
int ch = getch();
if (ch != ERR) {
ungetch(ch);
return 1;
} else {
return 0;
}
}
int main(void)
{
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
while (1) {
if (kbhit()) {
printw("Key pressed! It was: %d\n", getch());
}
}
}
或(认识到存在权衡),使用napms
暂停短时间,但减少使用的CPU时间:
#include <ncurses.h>
int kbhit(void)
{
int ch = getch();
if (ch != ERR) {
ungetch(ch);
return 1;
} else {
return 0;
}
}
int main(void)
{
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
while (1) {
if (kbhit()) {
printw("Key pressed! It was: %d\n", getch());
} else {
napms(20);
}
}
}
答案 1 :(得分:1)
尝试此操作以忽略缓冲的密钥重复:
int key;
if ((key = getch()) != ERR) {
while (getch() == key);
}
在上下文中:
//example.c
#include <ncurses.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int pos_x = 0;
int max_x = 0, max_y = 0;
int key = 0;
int on = 1;
initscr();
noecho();
cbreak();
curs_set(FALSE);
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
getmaxyx(stdscr,max_y,max_x);
while(1) {
clear();
mvprintw(0, 0, "Press, hold and release L-R arrow keys. Press UP/DOWN to toggle function.");
mvprintw(1, 0, "Skip buffered repeats: %s", (on ? "ON" : "OFF"));
mvprintw(2, pos_x, "@");
refresh();
usleep(50000);
getmaxyx(stdscr,max_y,max_x);
key = getch();
// skip buffered repeats
if (on) {
if (key != ERR) {
while (getch() == key);
}
}
//
switch (key) {
case KEY_LEFT:
pos_x += (pos_x > 0 ? -1 : 0); break;
case KEY_RIGHT:
pos_x += (pos_x < max_x - 1 ? 1 : 0); break;
case KEY_UP:
on = 1; break;
case KEY_DOWN:
on = 0; break;
}
}
endwin();
}
使用gcc example.c -lncurses -oexample && ./example