C очистить буфер ввода

Я одна часть моего приложения я использовал Sleep(5000) (Мне нужно подождать 5 сек)

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

Как я могу очистить буфер после сна?

Я старался cin.clear() а также setbuf(stdin, NULL) но они не могут очистить буфер, если в нем более одного символа.

Решение

Две функции, которые вы используете, не имеют ожидаемого эффекта:

  1. clear() не влияет на буфер вообще, а очищает флаги ошибок. То есть, если произошло неудачное чтение, устанавливается флаг ( std::ios_base::failbit ). Пока установлен любой флаг ошибки (есть еще несколько), поток не будет пытаться что-либо прочитать.
  2. setbuf(0, 0) влияет на то, что внутренний буфер потока не существует (вызовы с ненулевыми значениями имеют значение, определяемое реализацией, которое обычно «ничего не делает»). Как правило, это плохая идея, потому что это приводит к очень медленным потокам. Кроме того, клавиши, нажимаемые пользователем, вероятно, в любом случае сохраняются не в этом буфере, а во входном буфере операционной системы, пока они не будут отправлены в приложение (существуют платформо-зависимые способы отключения входного буфера операционной системы, например, на POSIX вы использовал tcsetattr() перевести вход в неканонический режим).

В любом случае отсутствие буфера на самом деле вам не поможет: пользователь вполне мог набрать правильный ввод. Правильный подход состоит в том, чтобы попытаться прочитать доступный ввод и, в случае неудачи, избавиться от оскорбительного символа (или символов). С этой целью вы попытаетесь прочитать входные данные, и если это не удастся, вы бы clear() поток и ignore() один или несколько символов (в этом примере игнорируется вся строка; вызов ignore() без параметров просто игнорировать один символ):

В любом случае вам всегда нужно проверять, что ввод был успешным, и несколько дополнительных строк просто добавляют немного кода восстановления.

Другие решения

Самый простой способ очистить буфер ввода с клавиатуры

Читайте также:  Давление газа для газовой плиты из баллона

просто поместите этот код в вашу программу, где бы вы ни хотели очистить свой буфер.

заголовочный файл, необходимый для этого conio.h

Кажется, это работает для Windows 10, скомпилированной с Code :: Blocks:

Затем вызывается откуда необходимо в вашем C ++ скрипте.

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


Как это влияет на программирование?

В некоторых случаях вам может потребоваться очистить ненужный буфер, чтобы получить следующий ввод в желаемом контейнере, а не в буфере предыдущей переменной. Например, в случае C после встречи с «scanf ()», если нам нужно ввести массив символов или символ, и в случае C ++, после встречи с оператором «cin», мы требуем ввести массив символов или строку, нам нужно очистить буфер ввода, иначе желаемый ввод будет занят буфером предыдущей переменной, а не нужным контейнером. При нажатии «Enter» (возврат каретки) на экране вывода после первого ввода, поскольку буфер предыдущей переменной был пространство для нового контейнера (как мы его не очищали), программа пропускает следующий ввод контейнера.

В случае программирования C

// C код, чтобы объяснить, почему нет
// очищаем входной буфер
// вызывает нежелательные выходы
#include

// Сканирование ввода от пользователя —

// Сканирование символа от пользователя

// Печать массива символов,

printf ( "%s
" , str);

// Это не печатает

В случае C ++

// C ++ код, объясняющий почему
// не очищаем ввод
// буфер вызывает нежелательное
// выводы
#include
#include

using namespace std;

// Введите ввод от пользователя

// Получить ввод от пользователя —

// Печать строки: это делает

// не печатать строку

В обоих приведенных выше кодах вывод не распечатывается должным образом. Причиной этому является занятый буфер. Символ «/ n» остается там в буфере и читается как следующий ввод.

Читайте также:  Ppp имя пользователя ppp пароль откуда брать

Как это можно решить?

В случае C:

    Использование «while ((getchar ())! = ‘/ N’); ” : Ввод« while ((getchar ())! = ‘/ N’); »читает символы буфера до конца и отбрасывает их (включая символ новой строки) и использует их после того, как инструкция« scanf () »очищает входной буфер и позволяет вводить в нужный контейнер.

// C код, объясняющий, почему добавление
// "while ((getchar ())! = ‘/ n’);"
// после оператора "scanf ()"
// очищает входной буфер
#include

// сканировать ввод от пользователя —

// сбрасывает стандартный ввод

// (очищает входной буфер)

while (( getchar ()) != ‘
‘ );

// сканируем символ от пользователя —

// Печать массива символов,

printf ( "%s
" , str);

// Печать символа a: It

// на этот раз напечатаем ‘a’

  1. Использование «fflush (stdin)» : ввод «fflush (stdin)» после оператора «scanf ()» также очищает входной буфер, но его использование исключается и называется «неопределенным» для входного потока согласно C ++ 11 стандартов.

В случае C ++:

    Использование «cin.ignore (numeric_limits :: max (), ‘/ n’); » : — Ввод« cin.ignore (numeric_limits :: max (), ‘/ n’); »после оператора« cin »отбрасывает все во входном потоке, включая символ новой строки.

// C ++ код, чтобы объяснить, как
// "cin.ignore (numeric_limits
// :: max (), ‘/ n’); "
// отбрасывает входной буфер
#include

// для numeric_limits
#include

using namespace std;

// Введите ввод от пользователя

// отбрасывает входной буфер

cin.ignore(numeric_limits ::max(), ‘
‘ );

// Получить ввод от пользователя —

// Печать строки: это

// сейчас напечатает строку

    Использование «cin.sync ()»: ввод «cin.sync ()» после оператора «cin» отбрасывает все, что осталось в буфере. Хотя «cin.sync ()» работает не во всех реализациях (в соответствии со стандартами C ++ 11 и выше).

// C ++ код, объясняющий, как "cin.sync ();"
// отбрасывает входной буфер
#include
#include
#include

Читайте также:  Banki ru купоны ozon

using namespace std;

// Введите ввод от пользователя

// Сбрасывает входной буфер

// Получить ввод от пользователя —

// Печать строки — это

// сейчас напечатает строку

    Использование «cin >> ws»: ввод «cin >> ws» после оператора «cin» указывает компилятору игнорировать буфер, а также отбрасывать все пробелы перед фактическим содержимым строки или символьного массива.

// C ++ код, объясняющий, как "cin >> ws"
// сбрасывает входной буфер вместе с
// начальные пробелы строки

using namespace std;

// Введите ввод от пользователя —

// Сбрасывает входной буфер и

// начальные пробелы строки

// Получить ввод от пользователя —

// печатает 4 и GeeksforGeeks:

// выполнит print a и s

Эта статья предоставлена Манджитом Сингхом . Если вам нравится GeeksforGeeks и вы хотите внести свой вклад, вы также можете написать статью и отправить ее по почте на contrib@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

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

Привет. Есть код.

Я только учу С++ и хочу сделать обработку неправильного введения пола друга. К примеру, пользователь вводит что-то кроме W и M и запрос на введение повторяется в цикле, что видно из кода. Также будет происходить, если пользователь введет много символов вместо одного. Но тут есть один момент. Дело в том, что так как тип переменной friend_sex char, то из потока ввода последовательность символов считывается посимвольно. Я написал abcd , допустим, но считалось сначала a , потом (если это в цикле, берется второй символ и происходит проверка, и так до конца). По сути, если написать abcMf , то на проверке четвертого символа цикл завершится, ибо проверка будет пройдена.