11

私のプログラム (これはたまたま Perl にありますが、この質問は Perl 固有のものではないと思います) は、プログラムのある時点でステータス メッセージを出力Progress: x/yyします。xyyProgress: 4/38

新しいステータス メッセージが出力されたときに、以前の出力を「上書き」して、画面がステータス メッセージでいっぱいにならないようにしたいと思います。これまでのところ、私はこれを試しました:

my $progressString = "Progress\t$counter / " . $total . "\n";
print $progressString;
#do lots of processing, update $counter
my $i = 0;
while ($i < length($progressString)) {
    print "\b";
    ++$i;
}

に改行を含めると、バックスペース文字が出力されません$progressString。ただし、改行を省略すると、出力バッファーはフラッシュされず、何も出力されません。

これに対する良い解決策は何ですか?

4

5 に答える 5

12

STDOUT で autoflush を使用します。

local $| = 1; # Or use IO::Handle; STDOUT->autoflush;

print 'Progress: ';
my $progressString;
while ...
{
  # remove prev progress
  print "\b" x length($progressString) if defined $progressString;
  # do lots of processing, update $counter
  $progressString = "$counter / $total"; # No more newline
  print $progressString; # Will print, because auto-flush is on
  # end of processing
}
print "\n"; # Don't forget the trailing newline
于 2011-02-15T20:46:18.870 に答える
4

言う

$| = 1

プログラムの早い段階で、出力バッファーの自動フラッシュをオンにします。

また、「\r」を使用してカーソルを行頭に戻すことも検討してください。戻す必要があるスペースの数を明示的に数えようとするのではありません。

あなたが言ったように、進行状況カウンターの実行中に改行を印刷しないでください。そうしないと、古い行を上書きする代わりに、別の行に進行状況を印刷します。

于 2011-02-15T20:47:54.210 に答える
3

私はそれがあなたが求めたものではないことを知っていますが、おそらくそれ以上です. 私はこの同じ問題に遭遇したので、それに対処するのではなく、Term::ProgressBar見栄えの良いものを使用することに行きました。

于 2011-02-16T05:51:20.777 に答える
1

ANSIエスケープコードを使用して、カーソルを直接制御することもできます。または、Term::ReadKeyを使用して同じことを行うことができます。

于 2011-02-15T23:42:28.657 に答える
0

私は今日、これに似た何かに取り組まなければなりませんでした。行全体を再印刷しても構わない場合は、次のようにすることができます。

print "\n";
while (...) {
     print "\rProgress: $counter / $total";
     # do processing work here
     $counter++;
}
print "\n";

「\r」文字は改行です。カーソルを行頭に戻します。そうすれば、印刷すると、以前の進捗通知のテキストが上書きされます。

于 2011-02-15T22:31:26.093 に答える