在C中检测键盘事件

sqxo8psd  于 2023-11-16  发布在  其他
关注(0)|答案(5)|浏览(145)

如何在不使用第三方库的情况下检测C语言中的键盘事件?我应该使用信号处理吗?

yzxexxkh

yzxexxkh1#

没有一个标准的方法,但这些应该让你开始。
窗口:

  1. getch();

字符串
Unix:
使用W. Richard Stevens的《Unix编程》一书中的代码将终端设置为raw模式,然后使用read()。

  1. static struct termios save_termios;
  2. static int term_saved;
  3. int tty_raw(int fd) { /* RAW! mode */
  4. struct termios buf;
  5. if (tcgetattr(fd, &save_termios) < 0) /* get the original state */
  6. return -1;
  7. buf = save_termios;
  8. buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
  9. /* echo off, canonical mode off, extended input
  10. processing off, signal chars off */
  11. buf.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON);
  12. /* no SIGINT on BREAK, CR-toNL off, input parity
  13. check off, don't strip the 8th bit on input,
  14. ouput flow control off */
  15. buf.c_cflag &= ~(CSIZE | PARENB);
  16. /* clear size bits, parity checking off */
  17. buf.c_cflag |= CS8;
  18. /* set 8 bits/char */
  19. buf.c_oflag &= ~(OPOST);
  20. /* output processing off */
  21. buf.c_cc[VMIN] = 1; /* 1 byte at a time */
  22. buf.c_cc[VTIME] = 0; /* no timer on input */
  23. if (tcsetattr(fd, TCSAFLUSH, &buf) < 0)
  24. return -1;
  25. term_saved = 1;
  26. return 0;
  27. }
  28. int tty_reset(int fd) { /* set it to normal! */
  29. if (term_saved)
  30. if (tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
  31. return -1;
  32. return 0;
  33. }

展开查看全部
wi3ka0sx

wi3ka0sx2#

那么好的老kbhit呢?如果我正确理解了这个问题,这将起作用。Here是Linux上的kbhit实现。

8ljdwjyq

8ljdwjyq3#

不幸的是,标准C没有任何检测键盘事件的工具。你必须依赖于特定于平台的扩展。信号处理对你没有帮助。

zwghvu4y

zwghvu4y4#

你真的应该使用第三方库。在ANSI C中绝对没有独立于平台的方法来做这件事。信号处理不是方法。

yizd12fk

yizd12fk5#

我有点迟了,但是:
其基本思想是将终端设置为非规范模式,以便您可以单独读取每个按键。

  1. #include <stdio.h>
  2. #include <termios.h>
  3. #include <unistd.h>
  4. void setNonCanonicalMode() {
  5. struct termios term;
  6. tcgetattr(STDIN_FILENO, &term);
  7. term.c_lflag &= ~(ICANON | ECHO);
  8. tcsetattr(STDIN_FILENO, TCSANOW, &term);
  9. }
  10. void resetCanonicalMode() {
  11. struct termios term;
  12. tcgetattr(STDIN_FILENO, &term);
  13. term.c_lflag |= ICANON | ECHO;
  14. tcsetattr(STDIN_FILENO, TCSANOW, &term);
  15. }

字符串
这应该足够了。

展开查看全部

相关问题