更新命令行输出
我的程序(恰好是用 Perl 编写的,尽管我不认为这个问题是 Perl 特有的)在程序中的某一点以 Progress: x/yy
形式输出状态消息,其中 x
和 yy
是一个数字,例如:进度: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
中包含换行符,则不会打印退格字符。但是,如果我省略换行符,则输出缓冲区永远不会刷新并且不会打印任何内容。
对此有什么好的解决办法吗?
My program (which happens to be in Perl, though I don't think this question is Perl-specific) outputs status messages at one point in the program of the form Progress: x/yy
where x
and yy
are a number, like: Progress: 4/38
.
I'd like to "overwrite" the previous output when a new status message is printed so I don't fill the screen with status messages. So far, I've tried this:
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;
}
The backspace character won't print if I include a newline in $progressString
. If I leave out the newline, however, the output buffer is never flushed and nothing prints.
What's a good solution for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在程序早期的某处指定
打开输出缓冲区的自动刷新。
还可以考虑使用“\r”将光标移回行首,而不是尝试显式计算需要移回多少个空格。
就像你说的,在进度计数器运行时不要打印换行符,否则你将在单独的行上打印进度而不是覆盖旧行。
Say
somewhere early in your program to turn autoflushing on for the output buffer.
Also consider using "\r" to move the cursor back to the beginning of the line, rather than trying to explicitly count how many spaces you need to move back.
Like you said, don't print out a newline while your progress counter is running or else you will print out your progress on a separate line instead of overwriting the old line.
我知道这不完全是你所要求的,但可能更好。我遇到了同样的问题,所以没有太多地处理它,而是使用
Term::ProgressBar
看起来也不错。I know it's not quite what you asked for, but possibly better. I happened on this same problem and so rather than deal with it too much went to using
Term::ProgressBar
which looks nice too.我今天必须解决类似的问题。
如果您不介意重新打印整行,您可以执行以下操作:
“\r”字符是回车符 - 它将光标带回到行的开头。这样,您打印出的任何内容都会覆盖先前进度通知的文本。
I had to tackle something similar to this today.
If you don't mind reprinting the entire line, you could do something like this:
The "\r" character is a carriage return-- it brings the cursor back to the beginning of the line. That way, anything you print out overwrites the previous progress notification's text.
您还可以使用 ANSI 转义码直接控制光标。或者您可以使用 Term::ReadKey 来做同样的事情。
You can also use the ANSI escape codes to directly control the cursor. Or you can use Term::ReadKey to do the same thing.
将自动刷新与 STDOUT 结合使用:
Use autoflush with STDOUT: