【问题标题】:Flushing Perl STDIN buffer刷新 Perl STDIN 缓冲区
【发布时间】:2011-11-28 00:09:59
【问题描述】:

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

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

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

【问题讨论】:

  • 好的,我一直在寻找这个问题的答案 3 天了(不是每天的每个小时,但我会说每天至少 3 或 4 小时)但还没有找到一个答案,事实上我问过我的同事,他们也知道和使用 Perl,他们也不知道,所以我相信我付出的努力比你暗示的要多,除此之外,你呢?对如何做我的要求有任何想法吗?因为我已经浏览了您的链接,大约 3 天前,尝试以一种可以在逻辑上解决此问题的方式实现这些功能,但它没有工作。
  • use IO::Handle;STDIN-&gt;autoflush(1);
  • 谢谢你的回答,但是,这并没有解决问题,而且,我记得读过 autoflush 和 flush 只对输出有用,例如 STDERR 和 STDOUT,而不是输入。当我尝试你的建议时,我仍然得到我在 for 循环输出期间输入的字符以及我在 STDIN 输入的字符。
  • @JackManey:通常,“刷新”适用于输出,而不是输入。

标签: perl buffer stdin flush


【解决方案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 3STDIN 转换为 cbreak 模式,这意味着 STDIN 在每次按键后都会刷新。这就是为什么...
  • while(defined($key = ReadKey(-1))) {} 发生了。这将清除用户在计算昂贵的代码期间输入的字符。那么……
  • ReadMode 0 重置STDIN,您可以从STDIN 读取,就好像用户没有敲击键盘一样。

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

严格来说,ReadMode 2 是不需要的,但我把它放在那里是为了在用户敲击键盘时屏幕不会被文字弄得乱七八糟。

【讨论】:

    【解决方案2】:
    { local $/; <STDIN> }
    

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

    之后就可以正常读取STDIN了。

    【讨论】:

    • 这行不通。 &lt;STDIN&gt; 调用会阻塞,直到可以读取“记录”。但是如果$/undef,则记录不可能有结束,所以会阻塞直到到达EOF。
    【解决方案3】:

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

    【讨论】:

    • --刚刚意识到这只有在处理过程中有返回时才有效,否则它将暂停直到有人点击进入
    猜你喜欢
    • 1970-01-01
    • 2014-06-23
    • 2018-07-11
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多