有没有办法清除Perl中的STDIN缓冲区?我的程序的一部分有很长的输出(有足够的时间让某人输入几个字符)并在输出之后我要求输入,但是如果在输出期间输入了字符,它们将被“添加”到输入中输入的任何内容部分。这是我的问题的一个例子:
for(my $n = 0; $n < 70000; $n++){
print $n . "\n";
}
chomp(my $input = <STDIN>);
print $input . "\n";
输出将包括从for循环输出期间输入的任何字符。我怎么能禁用STDIN或刷新STDIN缓冲区(或任何其他方式不允许在调用之前将额外的字符插入STDIN)?
答案 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 3
将STDIN
变为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。