刷新Perl STDIN缓冲区

时间:2011-09-29 20:12:46

标签: perl buffer stdin flush

有没有办法清除Perl中的STDIN缓冲区?我的程序的一部分有很长的输出(有足够的时间让某人输入几个字符)并在输出之后我要求输入,但是如果在输出期间输入了字符,它们将被“添加”到输入中输入的任何内容部分。这是我的问题的一个例子:

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

输出将包括从for循环输出期间输入的任何字符。我怎么能禁用STDIN或刷新STDIN缓冲区(或任何其他方式不允许在调用之前将额外的字符插入STDIN)?

3 个答案:

答案 0 :(得分:13)

看起来您可以使用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 3STDIN变为cbreak模式,这意味着每次按键后都会刷新STDIN种类。这就是为什么......
  • while(defined($key = ReadKey(-1))) {}发生了。这将清除用户在计算代价高昂的代码中输入的字符。然后...
  • ReadMode 0重置STDIN,您可以从STDIN读取,就像用户没有敲击键盘一样。

当我在sleep(10)期间运行此代码并敲击键盘时,在提示后输入其他文本,它只打印出我出现提示后输入的文字。

严格来说,不需要ReadMode 2,但我把它放在那里,以便当用户敲击键盘时屏幕不会弄乱文字。

答案 1 :(得分:0)

我有同样的问题并通过在处理后丢弃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";

答案 2 :(得分:-4)

{ local $/; <STDIN> }

暂时 - 仅限于块的范围 - 将输入记录分隔符$ /设置为undef,这告诉perl只读取所有内容而不是一次读取一行。然后读取STDIN上可用的所有内容,并且不对它执行任何操作,从而刷新缓冲区。

之后,您可以正常阅读STDIN。

相关问题