【问题标题】:How to combine printf and readline in Perl如何在 Perl 中结合 printf 和 readline
【发布时间】:2013-02-28 17:07:37
【问题描述】:

我正在尝试用 readline 替换 STDIN。如果我使用 STDIN(如注释中的代码,请参阅代码),则光标在 同一行 中的 printf 输出后即可输入。但是使用 readline 的 printf 输出不知何故消失了,只有 readline 提示可见。我可以插入“打印”\n“;” (注释掉)在 printf 的下一行,它将提示移动到下一行,并且 printf 输出可见。但是,我希望有一个格式化的提示,并且光标直接在提示之后(同一行)。 printf 赋值比下面的例子要复杂一些。 printf 是否可行,或者我有什么选择? 提前谢谢。

#!/usr/bin/perl -w

use Term::ReadLine;
use Term::ReadKey;
my $term = Term::ReadLine->new('name');

printf "%-12s","Input: ";
# my $new_value = <STDIN>;
# print "\n";
my $new_value = $term->readline('--> ');

【问题讨论】:

标签: perl printf readline prompt


【解决方案1】:

printf 的输出延迟的原因是缓冲。为避免这种情况,您可以使用未缓冲的 STDERR,可能更适合这种输出:

printf STDERR '%-12s', 'Input: ';

或者,您可以更频繁地刷新 STDOUT:

local $| == 1;

另一种选择是使用sprintf 而不是printf 并将整个表达式放在提示符下:

my $new_value = $term->readline(sprintf '%-12s-->', 'Input: ');

【讨论】:

  • 我发现以与其命名一致的方式使用输出流很有用。所以,我不使用STDERR 来输出除错误或日志消息以外的任何内容。我发现推荐使用STDERR 的缓冲特性而不是与其名称一致的方式会适得其反。此外,$| 是一个标志。因此,分配一个值而不是增加或减少它是正确的做法。只有您的最后一个建议具有真正的价值:如果需要特定提示,则应提供完整的提示文本。
  • 您应该使用$|=1local $|=1; 而不是$|--。如果有人已经将其设置为 1,您最终将关闭自动冲洗。此外,它不会禁用缓冲,它只会导致 Perl 更频繁地刷新缓冲区的内容。这就是为什么它通常被称为autoflush variable
  • 感谢大家 - 有趣的讨论。我现在使用sprintf。只要情况像这里一样简单,它就可以正常工作。我学到了很多东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
相关资源
最近更新 更多