Как отменить пользовательский ввод, доставленный во время режима сна? - PullRequest
2 голосов
/ 02 апреля 2019

Я пытаюсь создать игру, используя терминал.Я спрашиваю, готов ли игрок, и затем делаю обратный отсчет с кодом ниже.Проблема в том, что все вводимые пользователем данные добавляются к следующему входному запросу, который делает программа.Я ищу способ отменить предыдущий ввод или полностью заблокировать его во время этой функции.

Я мог бы сделать цикл getchar, но для этого потребовался бы ввод данных пользователем после обратного отсчета (нажав клавишу ввода), который я нет хочу.

void countdown(void){
  printf("5\n");
  sleep(1);
  printf("4\n");
  sleep(1);
  printf("3\n");
  sleep(1);
  printf("2\n");
  sleep(1);
  printf("1\n");
  sleep(1);
  clearScreen(0); //clears terminal
}

Ответы [ 3 ]

4 голосов
/ 02 апреля 2019

Вы в принципе не можете; Понятие «отбрасывание пользовательского ввода в течение определенного промежутка времени» на самом деле не имеет никакого смысла для стандартного вывода и ввода, учитывая тот факт, что ваш ввод может происходить, например, из файла (проблема здесь в том, что «время» на самом деле это не та концепция, которая каким-либо образом существует в стандартных процедурах ввода / вывода).

Для этого вам понадобится терминальный API, и ничего подобного в стандартной библиотеке C нет, хотя есть библиотеки, которые предоставляют такие возможности (но вы уже сказали, что не хотите использовать внешние библиотеки).

1 голос
/ 02 апреля 2019

Один из способов - использовать нить для обратного отсчета.

Основной код запускает поток обратного отсчета, а затем зацикливается для получения ввода.

Если функция ввода возвращается до завершения потока или ввода неправильного ответа, игнорируйте ввод и повторите цикл.

0 голосов
/ 02 апреля 2019

Поскольку вы используете среду Linux, вы можете попробовать использовать tcflush()

Ссылка на документацию tcflush

Вот модифицированный пример вашего кода с использованием tcflush. Вы можете раскомментировать нижнюю часть и увидеть, что все, что было введено во время обратного отсчета, очищается из буфера stdio.

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

void main(){
        char str[100];
        printf("5\n");
        sleep(1);
        printf("4\n");
        sleep(1);
        printf("3\n");
        sleep(1);
        printf("2\n");
        sleep(1);
        printf("1\n");
        sleep(1);

        // arguments for tcflush: 
        // 0 is for stdin 
        // TCIFLUSH is to flush data received but not read
        tcflush(0,TCIFLUSH);

        // prove it works by uncommenting this code
//      printf("fgets is waiting");
//      fgets(str, sizeof(str), stdin);
//      printf("%s", str);

//      clearScreen(0); //clears terminal
}
...