Промывка буфера Perl STDIN - PullRequest
       55

Промывка буфера Perl STDIN

10 голосов
/ 30 сентября 2011

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

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

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

Ответы [ 3 ]

13 голосов
/ 30 сентября 2011

Похоже, что вы можете сделать это с помощью модуля 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 не нужен, но я поместил его туда, чтобы экран не загромождался текстом, когда пользователь стучит по клавиатуре.

0 голосов
/ 26 августа 2016

У меня была та же проблема, и я решил ее, просто отбросив что-либо в 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";
0 голосов
/ 30 сентября 2011
{ local $/; <STDIN> }

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

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

...