views:

294

answers:

6

I want to make a progress bar for my terminal application that would work something like:

 [XXXXXXX       ]

which would give a visual indication of how much time there is left before the process completes.

I know I can do something like printing more and more X's by adding them to the string and then simply printf, but that would look like:

 [XXXXXXX       ] 
 [XXXXXXXX      ] 
 [XXXXXXXXX     ] 
 [XXXXXXXXXX    ]

or something like that (obviously you can play with the spacing.) But this is not visually aesthetic. Is there a way to update the printed text in a terminal with new text without reprinting? This is all under linux, c++.

+8  A: 

try using \r instead of \n when printing the new "version".

for(int i=0;i<=100;++i) printf("\r[%3d%%]",i);
printf("\n");
Michael Krelin - hacker
works like a charm, thanks
ldog
+4  A: 

I'd say that a library like ncurses would be used to such things. curses helps move the cursor around the screen and draw text and such.

NCurses

KFro
Sounds like an overkill here.
Michael Krelin - hacker
Yeah, probably...just a suggestion if someone wants to get more fancy in the future ;)
KFro
Yeah... there could be a game of PONG going on while we wait for the progress bar. :D
kjfletch
thanks for the tip ;) I know about ncurses, I've used it before to make a terminal hangman game, but I wanted to ask around before using it cause I knew it was overkill
ldog
+3  A: 

Something like this:

std::stringstream out;
for (int i = 0; i< 10; i++)
{
  out << "X";
  cout << "\r" << "[" << out.str() << "]";
}

The sneaky bit is the carriage return character "\r" which causes the cursor to move to the start of the line without going down to the next line.

1800 INFORMATION
+1  A: 

'\r' will perform a carriage return. Imagine a printer doing a carriage return without a linefeed ('\n'). This will return the writing point back to the start of the line... then reprint your updated status on top of the original line.

kjfletch
+1  A: 

It's a different language, but this question might be of assistance to you. Basically, the escape character \r (carriage Return, as opposed to \n Newline) moves you back to the beginning of your current printed line so you can overwrite what you've already printed.

Tim
A: 

Another option is to simply print one character at a time. Typically, stdout is line buffered, so you'll need to call fflush(stdout) --

for(int i = 0; i < 50; ++i) {
   putchar('X'); fflush(stdout);
   /* do some stuff here */
}
putchar('\n');

But this doesn't have the nice terminating "]" that indicates completion.

NVRAM