当前位置: 首页 > 面试题库 >

C无阻塞键盘输入

樊桐
2023-03-14
问题内容

我正在尝试用C语言编写一个程序(在Linux上),该程序将循环直到用户按下某个键为止,但不要求按下键盘来继续每个循环。

有没有简单的方法可以做到这一点?我认为我可以做到这一点,select()但这似乎需要大量工作。

或者,有没有办法在程序关闭之前捕获ctrl- c按键进行清理,而不是非阻塞io?


问题答案:

如前所述,您可以使用sigactionctrl-c select陷阱或任何标准输入。

但是请注意,使用后一种方法时,您还需要设置TTY,使其处于一次字符模式,而不是一次行模式。后者是默认设置-
如果您输入一行文本,则在您按Enter键之前,它不会发送到正在运行的程序的stdin中。

您需要使用该tcsetattr()功能关闭ICANON模式,并且可能也禁用ECHO。从内存中,您还必须在程序退出时将终端设置回ICANON模式!

为了完整起见,这里有一些我刚刚删除的代码(nb:没有错误检查!),它设置了Unix TTY并模拟DOS
<conio.h>函数,kbhit()并且getch()

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>

struct termios orig_termios;

void reset_terminal_mode()
{
    tcsetattr(0, TCSANOW, &orig_termios);
}

void set_conio_terminal_mode()
{
    struct termios new_termios;

    /* take two copies - one for now, one for later */
    tcgetattr(0, &orig_termios);
    memcpy(&new_termios, &orig_termios, sizeof(new_termios));

    /* register cleanup handler, and set the new terminal mode */
    atexit(reset_terminal_mode);
    cfmakeraw(&new_termios);
    tcsetattr(0, TCSANOW, &new_termios);
}

int kbhit()
{
    struct timeval tv = { 0L, 0L };
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(0, &fds);
    return select(1, &fds, NULL, NULL, &tv);
}

int getch()
{
    int r;
    unsigned char c;
    if ((r = read(0, &c, sizeof(c))) < 0) {
        return r;
    } else {
        return c;
    }
}

int main(int argc, char *argv[])
{
    set_conio_terminal_mode();

    while (!kbhit()) {
        /* do some work */
    }
    (void)getch(); /* consume the character */
}


 类似资料:
  • 我安装了一个插件,允许我从代码中创建UML图。一切正常,直到我发现现在所有的键盘快捷键(如CTRL-X、CTRL-Z、CTRL-SPACE、CTRL-SHIFT-F等)除了CTRL-C和CTRL-V之外,现在需要单击右下角显示的小正方形。这是每一次都需要的。 这是出现的正方形的几个例子: 如果我点击消息或按回车键,我可以访问该功能。有人知道如何摆脱这个烦人的东西或者至少重置Eclipse相关的配置

  • 我有一个带感应帽的覆盆子皮。我制作了一个二进制时钟,我想在Sense hat的显示器上显示并保持更新。然而,我想要的能力,开关时钟与操纵杆中间。一切都很好,除了我的时钟的更新循环阻止任何新的输入一旦启动。 我一直在考虑如何解决这个问题。如何允许脚本/时钟保持运行,并且仍然接受来自操纵杆的新操作。但是一旦while循环开始,我就卡住了。我不知道该用谷歌搜索什么。我已经开始研究async/await,

  • 问题内容: 我实际上尝试在600毫秒的时间内完成上述操作,此后它不应允许读取,但bufferedreader的readline阻塞了。请帮助 问题答案: 您可以使用BufferedReader.available()> 0检查是否有要读取的字符。

  • 问题内容: 有没有一种方法可以执行不冻结浏览器的同步AJAX查询?在我看来,在大多数情况下,同步请求要容易得多,但是它们阻止了代码其他部分的执行,这是一个真正的杀手。有没有办法获得同步AJAX而没有负面影响?(是的,我意识到术语“同步AJAX”是矛盾的。) 问题答案: 在即将到来的ECMAScript 2016(ES7)标准中,提供了一组新的语言关键字,这些关键字旨在执行与您似乎正在寻找的目标非常

  • 我编写了一个简单的类,我计划将其扩展为客户端套接字编程应用程序的一部分。类涉及一个BlockingQueue(我从这里复制了代码:相当于Java的BlockingQueue的C++)。当我创建了下面的包装类的一个实例后,我打算让它生成一个单独的线程,该线程只需执行BlockingQueue上阻塞的printer()函数,直到有一个或多个字符串可用,然后它只需将字符串打印到控制台窗口。在我的预期应用

  • 以上是我的源码,想要代码实现不回车就读取键盘输入