我想为我的终端应用程序创建一个进度条,它的工作方式如下:
[XXXXXXX ]
可以直观地显示流程完成前剩余的时间。
我知道我可以通过将它们添加到字符串然后只是printf来打印越来越多的X,但这看起来像是:
[XXXXXXX ]
[XXXXXXXX ]
[XXXXXXXXX ]
[XXXXXXXXXX ]
或类似的东西(显然你可以使用间距。)但这在视觉上不美观。有没有办法用新文本更新终端中的打印文本而无需重新打印?这都是linux,c ++。
答案 0 :(得分:43)
在打印新“版本”时尝试使用\r
代替\n
。
for(int i=0;i<=100;++i) printf("\r[%3d%%]",i);
printf("\n");
答案 1 :(得分:10)
我会说像ncurses这样的库会用于这样的事情。 curses有助于在屏幕上移动光标并绘制文本等。
答案 2 :(得分:7)
这样的事情:
std::stringstream out;
for (int i = 0; i< 10; i++)
{
out << "X";
cout << "\r" << "[" << out.str() << "]";
}
偷偷摸摸的位是回车符“\ _ r”,它会使光标移动到行的开头而不会下到下一行。
答案 3 :(得分:3)
其他人已经指出你可以使用\r
返回当前行的开头,并覆盖整行。
另一种可能性是使用退格符(“\ b”)来擦除一些空格,并仅覆盖那些空格。这可以有几个优点。首先,它显然避免了必须重新生成线上的所有东西,这有时可能是轻微的痛苦(虽然这是相当不寻常的)。其次,它可以避免在显示数据时出现一些痛苦(例如)在写入时缩小尺寸 - 例如,如果您显示从100到0的倒计时,则\r
要小心覆盖整个前一个长度,否则你的倒计时将从(例如)100变为990(即保持前一个“0”完整)。
但请注意,虽然行内的后退空间通常有效,但行开头的退格可能会或可能不会将光标/写入位置移回上一行。对于大多数实际用途,您只能在一行内移动。
答案 4 :(得分:1)
'\ r'将执行回车。想象一下打印机在没有换行符('\ n')的情况下进行回车。这会将写入点返回到行的开头...然后在原始行的顶部重新打印更新后的状态。
答案 5 :(得分:1)
这是一种不同的语言,但this question可能对您有所帮助。基本上,转义字符\ r \ n(回车符,而不是\ n换行符)会将您移回当前打印行的开头,以便您可以覆盖已打印的字符。
答案 6 :(得分:1)
另一种选择是一次只打印一个字符。通常,stdout是行缓冲的,因此您需要调用 fflush(stdout) -
for(int i = 0; i < 50; ++i) {
putchar('X'); fflush(stdout);
/* do some stuff here */
}
putchar('\n');
但是这没有好的终止“]”表示完成。
答案 7 :(得分:0)
我前段时间写过这个加载栏工具。可能有用......
https://github.com/BlaDrzz/CppUtility/tree/master/LoadingBar
您可以在此处自定义任何内容。
int max = 1000;
LoadingBar* lb = new LoadingBar(10, 0, max);
for (size_t i = 0; i <= max; i++)
{
lb->print();
lb->iterate();
}
cout << lb->toString() << endl;
非常简单且可自定义的实现..