我写了一个倒数计时器功能。
我想以这种方式打印,从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);
}
答案 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)
你“正在遭受缓冲”。在开头设置$|--
以关闭标准输出缓冲。