键盘捕获C

时间:2012-06-26 01:02:37

标签: c

所以我正在考虑如何在C中捕获键盘活动。众所周知,我们可以键入内容并按Enter键以输入我们想要发送到计算机的任何内容。但第一个问题是,如何输入一些不可用的字符,如向上箭头,向下箭头(特别是这两个人,因为我使用的是Linux,但是想要将它们用于默认含义以外的东西),shift,ctrl等等。第二,如何在我们按任意键后立即进行程序,所以我们不需要一直输入和输入。 (就像在Windows中“按任意键继续”)。

4 个答案:

答案 0 :(得分:2)

有两种方式。

使用stty命令。

  • 您可以在使用system ("/bin/stty raw");
  • 之前添加getchar()
  • 有关详细信息,请man stty

使用termios.h here

  • 你应该改变你的tty模式,如newt.c_lflag &= ~(ICANON | ECHO);
  • 了解详情,请man termios.h

答案 1 :(得分:1)

在DOS时代,有一个kbhit()功能。如果您需要该功能,可以查看以下主题:kbhit() for linux

我依旧回忆起尝试用户Thantos的功能而且工作得相当好。

我建议您先阅读tcgetattr()tcsetattr()功能的内容。

答案 2 :(得分:0)

“通用”方法是getchar()。 Getchar()“使用”缓冲输入“:在用户按下”Enter“之前,您实际上并未获得任何输出。除非您使用命令提示符(或者使用命令提示符),否则它不适用当量)。

旧的DOS方式是来自“conio.h”的getch()和getche()。在面向现代操作系统的现代C / C ++库中不存在该方法。

建议:

如果要创建文本模式UI(特别是在Linux上),请查看ncurses:

如果您想编写游戏(在Windows或Linux上),请查看SDL:

=== ADDENDUM ===

我仍然推荐一个库...但这里有一个函数,用于说明Linux下的“原始键盘输入”(又名“未经烹煮”或“非规范”输入):

http://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>

void changemode(int);
int  kbhit(void);

int 
main(int argc, char *argv[])
{
  int ch;
  changemode(1);
  while ( !kbhit() )
  {
    putchar('.');
  }

  ch = getchar();

  printf("\nGot %c\n", ch);

  changemode(0);
  return 0;
}

void 
changemode(int dir)
{
  static struct termios oldt, newt;

  if ( dir == 1 )
  {
    tcgetattr( STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);
  }
  else
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}

int 
kbhit (void)
{
  struct timeval tv;
  fd_set rdfs;

  tv.tv_sec = 0;
  tv.tv_usec = 0;

  FD_ZERO(&rdfs);
  FD_SET (STDIN_FILENO, &rdfs);

  select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
  return FD_ISSET(STDIN_FILENO, &rdfs);

}

答案 3 :(得分:0)

如果您使用Linux,键盘输入的最佳选择是GNU readline库。

如果您需要,它提供开箱即用的所有功能,包括emacs和vi编辑模式。

/* A static variable for holding the line. */
static char *line_read = (char *)NULL;

/* Read a string, and return a pointer to it.  Returns NULL on EOF. */
char *
rl_gets ()
{
    /* If the buffer has already been allocated, return the memory to the free pool. */
    if (line_read)
    {
        free (line_read);
        line_read = (char *)NULL;
    }

    /* Get a line from the user. */
    line_read = readline ("");

    /* If the line has any text in it, save it on the history. */
    if (line_read && *line_read)
        add_history (line_read);

    return (line_read);
}

MIT有一些很棒的教程。