Как я могу сбросить непрочитанные данные из очереди ввода tty в системе UNIX?
Моя программа должна читать только один символ со стандартного ввода, поэтому я использую read(0, buffer, 1)
.
Но если пользователь вставляет более одного символа, они остаются в некотором буфере, и когда я снова вызываю read
, они все еще там.
Итак, как я могу отбросить эти символы?
Я хочу, чтобы при повторном вызове read
буфер заполнялся новым символом, а не старыми.
Пример:
У меня есть read(0, buffer, 1)
, и пользователь пишет abcde. Мой буфер содержит (и это правильно), но затем я вызываю read(0, buffer, 1)
снова, и я хочу, чтобы следующий символ, написанный пользователем, теперь, а не ранее написанный b.
Ответы
Ответ 1
Когда ваша программа хочет начать чтение символов, она должна слить буфер существующих символов, а затем ждать, чтобы прочитать символ.
В противном случае он будет читать последний введенный символ, а не последний символ, введенный после этого.
Естественно, вам не нужно ничего делать с прочитанными символами; но вам нужно их прочитать.
Ответ 2
Ответ POSIX tcflush()
: очистить не передаваемые выходные данные, нечитаемые входные данные или и то, и другое. Существует также tcdrain()
, который ожидает вывода, которую нужно передать. Они были в POSIX, поскольку был стандарт POSIX (1988 для пробной версии), хотя я не помню, чтобы когда-либо их использовали напрямую.
Пример программы
Скомпилируйте этот код, чтобы получившаяся программа была вызвана tcflush
:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
int main(void)
{
char buffer[20] = "";
read(0, buffer, 1);
printf("%c\n", buffer[0]);
tcflush(0, TCIFLUSH);
read(0, buffer, 1);
printf("%c\n", buffer[0]);
tcflush(0, TCIFLUSH);
return 0;
}
Пример диалога
$ ./tcflush
abc
a
def
d
$
Похоже, что доктор заказал. Без второго tcflush()
оболочка жалуется, что не может найти команду ef
. Вы можете поместить tcflush()
перед первым чтением, если хотите. Это не было необходимо для моего простого тестирования, но если бы я использовал sleep 10; ./tcflush
, а затем набрал вперед, это изменило бы его.
Протестировано на RHEL 5 Linux на машине x86/64, а также в Mac OS X 10.7.4.