Получите ключи, как только они будут нажаты на консоли Unix - PullRequest
0 голосов
/ 17 мая 2018

Я разрабатываю программу на C ++ для Linux, чтобы использовать ее в качестве узла ROS (подробнее о ROS ).

Консоли Unix буферизуют всю строку текста до тех пор, пока пользователь не нажмет Enter, но мне нужно получить нажатие клавиши, как только пользователь нажмет клавишу.

Как я могу это сделать?

Я не заинтересован в создании переносимого кода. Это только занятие для моего курса в университете.

Кстати, я использую Ubuntu 16.04.4 LTS, а оболочка - bash.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Это функция терминала, поэтому, чтобы отключить эту функцию, вам потребуется перенастроить этот терминал. В 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);
0 голосов
/ 17 мая 2018

Кажется, вам нужен своего рода "небуферизированный" 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;
}
...