質問

私のプログラム(これはPerlにありますが、この質問はPerl固有のものではないと思います)は、次の形式のプログラムのある時点でステータスメッセージを出力 Progress: x/yy ここで xyy のような数です: Progress: 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.ただし、改行を省略すると、出力バッファがフラッシュされることはなく、何も出力されません。

これのための良い解決策は何ですか?

役に立ちましたか?

解決

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

他のヒント

言う

$| = 1

プログラムの初期のどこかで、出力バッファのオートフラッシュをオンにします。

また、戻る必要があるスペースの数を明示的にカウントするのではなく、" "を使用してカーソルを行の先頭に戻すことを検討してください。

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

私はそれがあなたが求めたものではないことを知っていますが、おそらくより良いです。私はこの同じ問題で起こったので、それに対処するのではなく、あまりにも多くを使用して行きました Term::ProgressBar それも素敵に見えます。

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

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

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

" "文字はキャリッジリターンであり、カーソルを行の先頭に戻します。このようにして、印刷すると、以前の進行状況通知のテキストが上書きされます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top