How to display a progress indicator in pure C/C++ (cout/printf)?
Solution 1
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;
[> ] 0 %
[===========> ] 15 %
[======================> ] 31 %
[=================================> ] 47 %
[============================================> ] 63 %
[========================================================> ] 80 %
[===================================================================> ] 96 %
Note that this output is shown one line below each other, but in a terminal emulator (I think also in Windows command line) it will be printed on the same line.
At the very end, don't forget to print a newline before printing more stuff.
If you want to remove the bar at the end, you have to overwrite it with spaces, to print something shorter like for example "Done."
.
Also, the same can of course be done using printf
in C; adapting the code above should be straight-forward.
Solution 2
You can use a "carriage return" (\r) without a line-feed (\n), and hope your console does the right thing.
Solution 3
For a C
solution with an adjustable progress bar width, you can use 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% [|||||||||||||||||||||||||||||||||||||||||| ]
Solution 4
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 may do what you need and I believe it is a header only library so nothing to link
Solution 5
You can print a carriage return character (\r
) to move the output "cursor" back to the beginning of the current line.
For a more sophisticated approach, take a look at something like ncurses (an API for console text-based interfaces).
xmllmx
Updated on July 08, 2022Comments
-
xmllmx almost 2 years
I'm writing a console program in C++ to download a large file. I know the file size, and I start a work thread to download it. I want to show a progress indicator to make it look cooler.
How can I display different strings at different times, but at the same position, in cout or printf?
-
leemes over 11 years+ manual flush, otherwise it will not be shown immediately because the output is buffered.
-
leemes over 11 years+ manual flush, otherwise it will not be shown immediately because the output is buffered.
-
Alexey Frunze over 11 years+
'\b'
for moving the cursor one position left. -
Ali over 11 yearsAnd if the user accidentaly hits the enter it breaks down :( Apart from that, it is perhaps the most portable solution, +1.
-
leemes over 11 years@Ali To avoid that, you would have to disable echoing (see
man termios
) -
Ali over 11 years@leemes
#include <termios.h>
, try that on M$ Windows :) Anyway, thanks for the tip, I will probably try that on Linux. -
Leo over 11 years+1 for ncurses. Definitely the way to go if you want to do anything a bit more complex.
-
leemes over 11 years@Ali There might be an equivalent for W1ndOw$, but I don't know it. ;)
-
Robb1 almost 7 yearsWatch out, there should be no
';'
at the end of the first#define
! -
horro over 6 yearsThis is the simplest and best solution I have found so far
-
YuMS over 5 yearsUsing
"\r\e[0K"
could also help clean the line. (tested under linux) -
momo123 about 4 yearsIs there a way to display an ascii character instead of | ? Thanks
-
Sylvain about 3 yearsWhat is the meaning of the last part, why is there a
""
for the last argument of theprintf()
? -
razz about 3 years@Sylvain The string in the square brackets has two parts; left and right. The left part consists of
lpad
characters ofPBSTR
printed using the%.*s
specifier, while the right part consists ofrpad
length of a space left-padded string which we chose to be empty "" so that we only printrpad
spaces using the%*s
specifier. -
Sylvain almost 3 yearsOh the right side is already "space left-padded". Thanks !! Great solution indeed.
-
Felierix about 2 yearsYou don't use system() and especially the color command. Use
SetConsoleTextAttribute(hConsole, color)
instead and don't forget to reset (color 7). -
XorOrNor about 2 yearsI think "percentage" parameter name is misleading as the function expects fraction of one ie. 0.1, 0.2, 0.5 and so on, not the percentage ie. 10.0, 20.0, 50.0.