просмотреть входной буфер и сбросить лишние символы в C

StackOverflow https://stackoverflow.com/questions/844847

  •  20-08-2019
  •  | 
  •  

Вопрос

Если я хочу получить ввод одного символа в C, как мне проверить, были ли отправлены дополнительные символы, и если да, то как мне это очистить?

Есть ли функция, которая действует как getc(stdin), но не предлагает пользователю ввести символ, поэтому я могу просто ввести while(getc(stdin)!=EOF);?Или функция, которая просматривает следующий символ в буфере, и если она не возвращает NULL (или что-то еще), я мог бы вызвать (другую) функцию, которая сбрасывает стандартный ввод?

Редактировать

Итак, сейчас Scanf, кажется, делает свое дело, но есть ли способ заставить его прочитать весь строка, до новой строки?Вместо ближайшего пробела?Я знаю, что могу просто поместить «%s %s %s» или что-то еще в строку формата, но могу ли я обрабатывать произвольное количество пробелов?

Это было полезно?

Решение

Вы не можете очистить входной поток.Если вы это сделаете, вы вызовете неопределенное поведение.Лучше всего сделать:

int main() {
  int c = getchar();
  while (getchar() != EOF);
  return 0;
}

Использовать scanf магия:

#include <stdio.h>
#include <stdlib.h> 

#define str(s) #s
#define xstr(s) str(s)
#define BUFSZ 256

int main() {
  char buf[ BUFSZ + 1 ];
  int rc = scanf("%" xstr(BUFSZ) "[^\n]%*[^\n]", buf);
  if (!feof(stdin)) {
    getchar();
  }
  while (rc == 1) {
    printf("Your string is: %s\n", array);
    fflush(stdout);
    rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
    if (!feof(stdin)) {
        getchar();
    }
   }
   return 0;
}

Другие советы

Вы можете использовать getline прочитать всю строку ввода.

В качестве альтернативы (в ответ на ваш первоначальный вопрос) вы можете позвонить select или poll на стандартный ввод, чтобы узнать, есть ли дополнительные символы для чтения.

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

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

Проблема в том, что в дополнение к введенному мной символу, возвращаемому функцией getchar(), нажатие клавиши Enter (которое отправляет нажатие клавиши в программу) сохраняется во входном буфере.Этот (непечатаемый) символ новой строки затем возвращается функцией getchar() в цикле исправления ошибок, что в дальнейшем приводит ко второму сообщению об ошибке (поскольку символ новой строки не является ни «1», ни «2»). , ни «3».)

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

Не круто.

Однако, похоже, это удалось исправить следующим образом:

c = getchar();  // get first char in line
while(getchar() != '\n') ; // discard rest of buffer

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

Мы можем создать функцию для очистки буфера клавиатуры, например:

#include <stdio.h>

void clear_buffer(){
   char b;
   //this loop take character by character in the keyboard buffer using 
   //getchar() function, it stop when the variable "b" was
   //enter key or EOF.
   while (((b = getchar()) != '\n') && (b != EOF));
}

int main()
{
    char input;
    //get the input. supposed to be one char!
    scanf("%c", &input); 
    //call the clearing function that clear the buffer of the keyboard 
    clear_buffer(); 
    printf("%c\n",input); //print out the first character input
    // to make sure that our function work fine, we have to get the
    // input into the "input" char variable one more time
    scanf("%c", &input); 
    clear_buffer();  
    printf("%c\n",input);
    return 0;
}

Используйте чтение, которое потребует большого количества символов (более 1, возможно, 256), и посмотрите, сколько на самом деле будет возвращено.Если вы получите больше одного, вы знаете;если вы получите только один, это все, что есть в наличии.

Вы не упоминаете платформу, и это довольно быстро становится довольно сложным.Например, в Unix (Linux) обычный механизм вернет строку данных — возможно, тот символ, который вам нужен, и новую строку.Или, может быть, вы убедите своего пользователя ввести ^D (по умолчанию), чтобы отправить предыдущий символ.Или, может быть, вы используете функции управления, чтобы перевести терминал в необработанный режим (например, такие программы, как vi и emacs делать).

В Windows я не уверен — думаю, есть getch() функция, которая делает то, что вам нужно.

Почему бы вам не использовать scanf вместо getc, с помощью scanf вы можете получить всю строку.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top