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 回答