Промывочный буфер Perl STDIN

Есть ли способ очистить буфер STDIN в Perl? Часть моей программы имеет длительный вывод (достаточно времени, чтобы кто-то мог ввести несколько символов), и после этого вывода я запрашиваю ввод, но если символы были введены во время вывода, они "привязаны" к тому, что введено на входе часть. Вот пример моей проблемы:

for(my $n = 0; $n < 70000; $n++){
   print $n . "\n";
}
chomp(my $input = <STDIN>);
print $input . "\n";

Выход будет включать любые символы, введенные во время вывода из цикла for. Как я могу отключить STDIN или сбросить буфер STDIN (или любой другой способ не допустить добавления дополнительных символов в STDIN до его вызова)?

Ответ 1

Похоже, вы можете выполнить это с помощью Term::ReadKey:

#!perl

use strict;
use warnings;
use 5.010;

use Term::ReadKey;

say "I'm starting to sleep...";
ReadMode 2;
sleep(10);
ReadMode 3;
my $key;
while( defined( $key = ReadKey(-1) ) ) {}
ReadMode 0;
say "Enter something:";
chomp( my $input = <STDIN> );
say "You entered '$input'";

Вот что происходит:

  • ReadMode 2 означает "включить режим ввода в обычный режим, но отключить эхо". Это означает, что любое нажатие клавиатуры, которое пользователь делает, пока вы находитесь в своем дорогостоящем коде, не будет отображаться на экране. Он по-прежнему вводится в буфер STDIN, поэтому...
  • ReadMode 3 превращает STDIN в режим cbreak, что означает, что STDIN будет очищаться после каждого нажатия клавиши. Вот почему...
  • while(defined($key = ReadKey(-1))) {}. Это вымывание символов, введенных пользователем во время дорогостоящего кода. Тогда...
  • ReadMode 0 сбрасывает STDIN, и вы можете читать из STDIN, как если бы пользователь не ударил по клавиатуре.

Когда я запускаю этот код и нажимаю на клавиатуре во время sleep(10), затем введите другой текст после приглашения, он распечатает только текст, который я напечатал после появления приглашения.

Строго говоря, ReadMode 2 не нужен, но я помещаю его туда, чтобы экран не загромождал текст, когда пользователь натыкается на клавиатуру.

Ответ 2

У меня была такая же проблема и она была решена, просто отбросив что-нибудь в STDIN после обработки следующим образом:

for(my $n = 0; $n < 70000; $n++){
  print $n . "\n";
}
my $foo=<STDIN>;
print "would you like to continue [y/n]: ";
chomp(my $input = <STDIN>);
print $input . "\n";

Ответ 3

{ local $/; <STDIN> }

Это временно - ограничено областью действия блока - устанавливает $/, разделитель входных записей, чтобы быть undef, что говорит perl просто читать все, а не читать строку за раз. Затем читает все, что доступно на STDIN, и ничего не делает с ним, тем самым смывая буфер.

После этого вы можете читать STDIN как обычно.