在Unix控制台上按下键后立即接收密钥

时间:2018-05-17 15:01:04

标签: c++ linux terminal ros

我正在Linux上开发一个C ++程序,将其用作ROS节点(有关ROS的更多信息)。

Unix控制台缓冲整行文本,直到用户按Enter键,但我需要在用户按下键时立即接收击键。

我该怎么做?

我对做便携式代码不感兴趣。这只是我在大学课程的一项活动。

顺便说一句,我运行的是Ubuntu 16.04.4 LTS,shell是bash。

2 个答案:

答案 0 :(得分:2)

您似乎需要一种“无缓冲的”getchar

您应该尝试使用termios,例如:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

int main()
{
    struct termios old_tio, new_tio;
    unsigned char c;

    /* get the terminal settings for stdin */
    tcgetattr(STDIN_FILENO,&old_tio);

    /* we want to keep the old setting to restore them a the end */
    new_tio=old_tio;

    /* disable canonical mode (buffered i/o) and local echo */
    new_tio.c_lflag &=(~ICANON & ~ECHO);

    /* set the new settings immediately */
    tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);

    do {
         c=getchar();
         printf("%d ",c);
    } while(c!='q');

    /* restore the former settings */
    tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);

    return 0;
}

答案 1 :(得分:1)

这是终端的一项功能,因此要关闭该功能,您需要重新配置该终端。在C ++中,就像这样:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

在任何初始化函数中:

struct termios original_termios, unbuffered_termios;

tcgetattr(STDIN_FILENO, &original_termios);
unbuffered_termios = original_termios;
unbuffered_termios.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &unbuffered_termios);

之后,您可以使用任何标准方法从文件stdin中读取单个字节(例如fread()getch())。请记住,某些按键在按下时会发送多个字节(例如光标键)。

完成您的工作后,您应该恢复原始设置,否则即使您的程序终止,终端也可能表现得很奇怪:

tcsetattr(STDIN_FILENO, TCSANOW, &original_termios);