заглянуть в буфер ввода и сбросить лишние символы в C - PullRequest
1 голос
/ 10 мая 2009

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

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

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

Так что сейчас, похоже, scanf добивается цели, но есть ли способ заставить его читать строку целом вплоть до новой строки? Вместо того, чтобы до ближайшего пробела? Я знаю, что могу просто поместить "% s% s% s" или что-то еще в строку формата, но могу ли я обработать произвольное количество пробелов?

Ответы [ 6 ]

4 голосов
/ 10 мая 2009

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

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;
}
1 голос
/ 29 сентября 2016

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

#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 голос
/ 27 мая 2009

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

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

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

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

Не круто.

Что, похоже, исправило это, так это:

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

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

1 голос
/ 10 мая 2009

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

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

0 голосов
/ 10 мая 2009

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

0 голосов
/ 10 мая 2009

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

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

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

...