Общий вариант использования
Я пытаюсь реализовать базовую оболочку.
Описание
Мне нужно читать пользовательский ввод, пока не будут нажаты некоторые разделители, чтобы можно было выполнить соответствующее действие. Этим разделителем может быть одна буква «а», одна буква «б» или одна буква «с».
Пример ввода будет выглядеть так (где > — приглашение оболочки):
> 111-222-333-444a
Ok, '111-222-333-444' entered
Почему мне нужен встроенный разделитель вместо разделителя новой строки?
Потому что я хотел бы прослушать событие клавиатуры, такое как «стрелка вверх», чтобы стереть текущую команду и распечатать последнюю команду (реализуя функцию истории).
Потому что я хотел бы прослушать событие клавиатуры, такое как «табуляция», для автоматического завершения текущей команды (реализация функции автозаполнения).
Что у меня есть до сих пор
До сих пор мой код выглядит так:
bool done = false;
char c;
while (!done && std::cin.get(c))
{
switch (c)
{
case 'a':
// Do something corresponding to 'a'
done = true;
break;
case 'b':
// Do something corresponding to 'b'
done = true;
break;
case 'c':
// Do something corresponding to 'c'
done = true;
break;
default:
// buffer input until a delimiter is pressed
break;
}
}
Однако цикл, похоже, выполняется только после нажатия клавиши «новая строка». Такое поведение убивает интерактивную сущность пользовательского ввода.
В чем вопрос?
Я знаю, что std::ostream буферизуется, поэтому содержимое не записывается на диск до тех пор, пока не произойдет какое-то событие, но как насчет std::istream. Это буферизовано? Если да, то как и как обойти это поведение?
Кроме того, я пометил этот вопрос как «домашнее задание», потому что, даже если это не школьное упражнение, это упражнение, которое я пытаюсь выполнить сам, и я не хочу выбирать только библиотеку, которая реализует все это. материал.