如何使用printf打印我的功能?

时间:2012-08-30 14:04:25

标签: perl

我写了一个倒数计时器功能。

我想以这种方式打印,从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);
}

2 个答案:

答案 0 :(得分:1)

问题是你正在使用\r(回车) - 它将回车键返回到字符串的最开头(因此在最佳情况下覆盖前5个字符) ; AND在没有“\n”的情况下导致奇怪的打印行为(因此可能不会在5个字符后打印任何其他内容)。


要解决您的问题,您需要在countdownnsleep()内的循环中执行此操作:

$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";

这就是为什么你需要在非常结束时打印“\ 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.
    

另外,您应该考虑使用现有的coundown / progress CPAN模块,而不是自己动手。

答案 1 :(得分:0)

你“正在遭受缓冲”。在开头设置$|--以关闭标准输出缓冲。