What would be an easy way of implementing a console-based progress indicator for a task that's being executed, but I can't anticipate how much time it would take?
I used to do this back when I coded in Clipper, and it was only a matter of iterating through the chars '/', '-', '\', '|' and positioning them in the same place.
Any way / links / libs for doing that (or something similar) in C++?
The target for this is *nix environments.
Edits:
A very simple way to do it is to print out a string followed by a '\r'
character. That is carriage return by itself and on most consoles, it returns the cursor to the beginning of the line without moving down. That allows you to overwrite the current line.
If you are writing to stdout or cout or clog remember to fflush or std::flush the stream to make it output the line immediately. If you are writing to stderr or cerr then the stream is unbuffered and all output is immediate (and inefficient).
A more complicated way to do it is to get into using a screen drawing library like curses. The Windows consoles have some other ways of setting them for direct screen writing but I don't know what they are.
You could try something like:
void
spinner(int spin_seconds) {
static char const spin_chars[] = "/-\\|";
unsigned long i, num_iterations = (spin_seconds * 10);
for (i=0; i<num_iterations; ++i) {
putchar(spin_chars[i % sizeof(spin_chars)]);
fflush(stdout);
usleep(100000);
putchar('\b');
}
}
Of course, this is non-standard because of the sub-second usleep()
and I'm not sure if there is any guarantee that \b
erases a character or not, but it works on most platforms. You can also try \r
instead if \b
doesn't do the trick. Otherwise, try to find a version of curses.
This should get you started:
#include <curses.h>
#include <unistd.h>
void spinner(int spin_seconds) {
static char const spin_chars[] = "/-\\|";
unsigned long i, num_iterations = (spin_seconds * 10);
for (i=0; i<num_iterations; ++i) {
mvaddch(0, 0, spin_chars[i & 3]);
refresh();
usleep(100000);
}
}
int main() {
initscr(); /* initializes curses */
spinner(10); /* spin for 10 seconds */
endwin(); /* cleanup curses */
return 0;
}
Make sure to link with either -lcurses
or -lncurses
. That should work on any UNIX alike out there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With