1

カウントダウンタイマーという機能を書きました。

このように印刷したい、00:05から

したがって、私はこれを行いましたが、正しく印刷されず、文が上書きされます。あなたはそれを修正するのを手伝ってもらえますか?

printf("\nStarts in %02d:%02d",countdownsleep(5));

# Sub for countdown
sub countdownsleep {
    my $x = shift;
    my $t = 1 *$x;
    my ($m,$s);
    my $stoptime = time + $t;
     while((my $now = time) < $stoptime) {
   #printf( "%02d:%02d\r", ($stoptime - $now) / 60, ($stoptime - $now) % 60);
   $m = ($stoptime - $now) / 60;
   $s = ($stoptime - $now) % 60;
    select(undef,undef,undef,1);
 }
 return ($m,$s);
}
4

2 に答える 2

1

問題は、\r(キャリッジリターン)を使用していることです-キャリッジを文字列の最初に返します(したがって、最良のシナリオでは最初の5文字を​​上書きします)。AND は、" " がない場合に奇妙な印刷動作を引き起こします\n(したがって、5 文字以降は何も印刷されない可能性があります)。


問題を解決するには、 countdownsleep () 内のループでこれを行う必要があります。

$prefix = "Starts in "; # could be passed in as parameter to countdownsleep()
printf( "$prefix %02d:%02d\r", ($stoptime - $now) / 60
                               , ($stoptime - $now) % 60);
# NOTE this ^^^ - now you re-print your prefix every time and not lose due to \r

そしてあなたの呼び出しで:

countdownsleep(5); print "\n"; # printing is done by the loop inside already
# or if you added a $prefix parameter to it:
countdownsleep("Starts in ", 5); print "\n";

VERY END に「\n」を出力する必要がある理由は次のとおりです。

$ perl -e '{print "1234567"; printf("1\r");}'

$ perl -e '{print "1234567"; printf("8\r"); print "\n";}' # Works now
12345678

# And this is what CR really dows
$ perl -e '{print "1234567"; printf("z\r");  printf("yy\r");  print "\n";}'
yy34567z
$ perl -e '{print "1234567"; printf("z\r");  printf("yy\r");  print "zzzz";}'
zzzz

言い換えれば、\r文字列の最後にキャリッジ リターン ( ) を改行 ( \n)なしで印刷すると、実際には文字列がまったく印刷されません。より具体的には、印刷されるはずだったすべてが消去されます。

文字列内の他の文字の前に( \r) を印刷すると、後続の文字が行の先頭から印刷され、既存の文字 (新しい文字と同じ数) が上書きされますが、後続の文字はそのまま保持されます。最後に が印刷されない限り、上書きされない文字は印刷されません\n

  • print "$something\r"; # prints nothing

  • print "$something\r$finish"; # prints $finish but not $something

    # $finish is assumed to not contain "\r"
    
  • print "$something\r$finish\n";

    # * prints $something (entirely)
    # * Moves to start of the line
    # * prints $finish overwriting as many characters  from $somthing as needed
    # * prints the rest of $something if it was longer than $finish
    # * prints newline.
    

別の注意として、独自のロールではなく、既存のカウントダウン/進行 CPAN モジュールの使用を検討する必要があります。

于 2012-08-30T14:23:12.143 に答える
0

あなたは「バッファリングに苦しんでいます」。$|--標準出力のバッファリングをオフにするには、最初に設定します。

于 2012-08-30T14:29:59.640 に答える