Как подготовить дескриптор файла stdin при нажатии клавиши? - PullRequest
1 голос
/ 31 мая 2019

У меня есть пользовательская функция _kbhit (), используемая для неблокирующего ввода символов.Функция _kbhit () использует select (), чтобы проверить, готов ли stdin к чтению.Но, наконец, у меня есть готовый стандартный ввод, если только я нажму RETURN.Как заставить это работать, когда я нажимаю любую клавишу?

void set_conio_terminal_mode()
{
    struct termios new_termios;

    /* take two copies - one for now, one for later */
    tcgetattr(0, &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);
}

static char _getch(void) {
    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 (1) {
        if (_kbhit()) {
            inputbuffer[inputlen] = _getch();
            if (inputbuffer[inputlen] >= 0x20 && inputbuffer[inputlen] < 0x7F) {
                putchar(inputbuffer[inputlen]);
                inputlen++;
            }
        }
    }
}

Я ожидал, что этот код выведет эхо, но он выведет всю строку сразу после того, как я нажму RETURN.

1 Ответ

1 голос
/ 31 мая 2019

Я думаю, что проблема в том, что - несмотря на вашу инициализацию атрибутов терминала с использованием cfmakeraw() - stdout все еще находится в режиме линейной буферизации.

Попробуйте установить стандартный вывод в небуферизованный режим.

setbuf(stdout, NULL);

, что эквивалентно

setvbuf(stdout, NULL, _IONBF, 0);

Это позволяет избежать необходимости звонить fflush(stdout); после каждого putchar(inputbuffer[inputlen]);.

Может быть способ сделать это, используя tcsetattr() вместо setvbuf(), но я не знаком с этим.

...