How to display progress indicator in pure C / C ++ (cout / printf)?

I am writing a C ++ console program to upload a large file. I know the file size, and I run the workflow to load. I want to show a progress indicator so that it looks cooler.

How to display different lines at different times, but in the same position, in cout or printf?

+59
c ++ c user-interface io c ++ 11
Jan 26 '13 at 18:02
source share
8 answers

You can use carriage return (\ r) without a string (\ n) and hope that your console does the right thing.

+43
Jan 26 '13 at 18:05
source share

With a fixed width of your output, use something like the following:

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; 

http://ideone.com/Yg8NKj

 [> ] 0 % [===========> ] 15 % [======================> ] 31 % [=================================> ] 47 % [============================================> ] 63 % [========================================================> ] 80 % [===================================================================> ] 96 % 

Please note that this output is displayed on one line below each other, but in the terminal emulator (I think also on the Windows command line) it will be printed on the same line.

At the very end, remember to print a new line before printing more things.

If you want to remove the panel at the end, you must rewrite it with spaces to print something shorter, for example, "Done." .

In addition, the same can be done using printf in C; adaptation of the above code should be straightforward.

+90
Jan 26 '13 at 18:11
source share

For solution C with an adjustable runtime, you can try the following:

 #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); } 

It will output something like this:

  75% [|||||||||||||||||||||||||||||||||||||||||| ] 
+17
Mar 30 '16 at 17:33
source share

Take a look at boost progress_display

http://www.boost.org/doc/libs/1_52_0/libs/timer/doc/original_timer.html#Class%20progress_display

I think it can do what you need, and I believe this is a header-only library, so nothing needs to be linked

+14
Jan 26 '13 at 21:28
source share

You can type the carriage return character ( \r ) to move the cursor output back to the beginning of the current line.

For a more sophisticated approach, take a look at something like ncurses (APIs for console text interfaces).

+8
Jan 26 '13 at 18:05
source share

Another way could be to display “dots” or any other character that you want. The code below will print a progress indicator [download view ...] as dots every 1 second.

PS: I use sleep here. Think twice if performance is a problem.

 #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; } 
+4
Feb 27 '15 at 14:00
source share

I know that I was a little late in answering this question, but I made a simple class that does exactly what you want. (keep in what I wrote using namespace std; before that.):

 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 }; 

Usage example:

 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; } 

Note. I made all class lines public so that the appearance of the panel can be easily changed.

+2
Mar 20 '16 at 19:42
source share

Here is a simple one I made:

 #include <iostream> #include <windows.h> using namespace std; int barl = 20; int main() { system("color 0e"); cout << "["; for (int i = 0; i < barl; i++) { Sleep(100); cout << ":"; } cout << "]"; } 
0
Dec 24 '17 at 10:30
source share



All Articles