如何在纯C / C ++(cout / printf)中显示进度指示器?
我正在用C ++编写一个控制台程序来下载一个大文件。 我已经知道文件的大小,我开始工作线程下载。 我想显示一个进度指示器,让它看起来更酷。
如何在不同的时间显示不同的string,但在相同的位置,在cout或printf?
您可以使用“回车”(\ r)而不用换行符(\ n),并希望您的控制台执行正确的操作。
使用固定宽度的输出,使用如下所示的内容:
float progress = 0.0; while (progress < 1.0) { int barWidth = 70; std::cout << "["; int pos = barWidth * progress; for (int i = 0; i < barWidth; ++i) { if (i < pos) std::cout << "="; else if (i == pos) std::cout << ">"; else std::cout << " "; } std::cout << "] " << int(progress * 100.0) << " %\r"; std::cout.flush(); progress += 0.16; // for demonstration only } std::cout << std::endl;
[> ] 0 % [===========> ] 15 % [======================> ] 31 % [=================================> ] 47 % [============================================> ] 63 % [========================================================> ] 80 % [===================================================================> ] 96 %
请注意,这个输出显示为一行在另一行之下,但是在一个terminal仿真器中(我想也是在Windows命令行中)它将被打印在同一行上 。
最后,不要忘记打印更多的东西之前打印一个换行符。
如果要在最后删除条形图,则必须用空格将其覆盖,以便打印出例如"Done."
。
而且,当然也可以用printf
中的printf
来完成。 适应上面的代码应该是直截了当的。
看看boost progress_display
http://www.boost.org/doc/libs/1_52_0/libs/timer/doc/original_timer.html#Class%20progress_display
我认为这可能会做你所需要的,我相信这是一个头只有图书馆,所以没有任何关联
您可以打印回车符( \r
)将输出“光标”移回当前行的开头。
对于一个更复杂的方法,看一下像ncurses(控制台基于文本的接口的API)。
对于具有可调节进度条宽度的C
解决scheme,您可以尝试以下操作:
#define PBSTR "
" #define PBWIDTH 60 void printProgress (double percentage) { int val = (int) (percentage * 100); int lpad = (int) (percentage * PBWIDTH); int rpad = PBWIDTH – lpad; printf ("\r%3d%% [%.*s%*s]", val, lpad, PBSTR, rpad, ""); fflush (stdout); }
它会输出这样的东西:
75% [
]
另一种方式可能是显示“点”或任何你想要的字符。下面的代码将打印进度指示器[sorting加载…]作为点每1秒。
PS:我在这里用睡觉。 考虑到性能,请三思。
#include<iostream> using namespace std; int main() { int count = 0; cout << "Will load in 10 Sec " << endl << "Loading "; for(count;count < 10; ++count){ cout << ". " ; fflush(stdout); sleep(1); } cout << endl << "Done" <<endl; return 0; }
我知道我在回答这个问题上迟了一会 ,但是我做了一个简单的课,就是你想要的。 (请记住,我写了using namespace std;
在此之前):
class pBar { public: void update(double newProgress) { currentProgress += newProgress; amountOfFiller = (int)((currentProgress / neededProgress)*(double)pBarLength); } void print() { currUpdateVal %= pBarUpdater.length(); cout << "\r" //Bring cursor to start of line << firstPartOfpBar; //Print out first part of pBar for (int a = 0; a < amountOfFiller; a++) { //Print out current progress cout << pBarFiller; } cout << pBarUpdater[currUpdateVal]; for (int b = 0; b < pBarLength - amountOfFiller; b++) { //Print out spaces cout << " "; } cout << lastPartOfpBar //Print out last part of progress bar << " (" << (int)(100*(currentProgress/neededProgress)) << "%)" //This just prints out the percent << flush; currUpdateVal += 1; } std::string firstPartOfpBar = "[", //Change these at will (that is why I made them public) lastPartOfpBar = "]", pBarFiller = "|", pBarUpdater = "/-\\|"; private: int amountOfFiller, pBarLength = 50, //I would recommend NOT changing this currUpdateVal = 0; //Do not change double currentProgress = 0, //Do not change neededProgress = 100; //I would recommend NOT changing this };
一个关于如何使用的例子:
int main() { //Setup: pBar bar; //Main loop: for (int i = 0; i < 100; i++) { //This can be any loop, but I just made this as an example //Update pBar: bar.update(1); //How much new progress was added (only needed when new progress was added) //Print pBar: bar.print(); //This should be called more frequently than it is in this demo (you'll have to see what looks best for your program) sleep(1); } cout << endl; return 0; }
注意:我公开了所有类的string,因此可以很容易地更改酒吧的外观。