Reputation: 756
My LAME (v3.99.5) outputs progress in console by moving up x lines in the console and overwriting the previous lines. It's pretty cool.
I've read in a different post that such behavior for a single line can be achieved with a mere "\r"
instead of "\n"
- although the post was for Ruby, it seems to be the same for C on my system at least:
#include <stdio.h>
#include <time.h>
int main() {
time_t t;
time_t t2;
time(&t);
t2 = t;
printf("%u\r", (unsigned int)t);
fflush(stdout);
while (1) {
if (t2 - t > 0) {
time(&t);
printf("%u\r", (unsigned int)t);
fflush(stdout);
}
time(&t2);
}
return 0;
}
The post further suggests a curses library can be used to make the same behavior multi-line.
What would be a boilerplate example of such code in C?
Upvotes: 2
Views: 1155
Reputation: 54475
The example shown by @purplepsycho has some issues, addressed in this revision (works with "any" X/Open Curses implementation):
#include <curses.h>
int main(int argc, char *argv[])
{
filter();
initscr();
// init time
time_t t = 0, t2;
time(&t2);
// main loop
while (1) {
if (t2 - t > 0)
{
time(&t);
erase();
mvprintw(1,1, "%u", (unsigned int)t);
refresh();
}
time(&t2);
}
endwin();
return 0;
}
That is:
initscr
for initializing curses (PDCurses provides a non-standard function Xinitscr
which is not what OP had in mind: it certainly is not often used).erase
rather than clear
(to avoid screen-flicker):
The
clear
andwclear
routines are likeerase
andwerase
, but they also callclearok
, so that the screen is cleared completely on the next call towrefresh
for that window and repainted from scratch.
filter
to keep the output on a single line. filter.c
in ncurses-examples).Better than erase()
would be wclrtoeol()
, called after the mvprintw
.
Upvotes: 0
Reputation: 158
According to http://falsinsoft.blogspot.com/2014/05/set-console-cursor-position-in-windows.html
Windows:
void SetCursorPos(int XPos, int YPos)
{
COORD Coord;
Coord.X = XPos;
Coord.Y = YPos;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coord);
}
Linux:
void SetCursorPos(int XPos, int YPos)
{
printf("\033[%d;%dH", YPos+1, XPos+1);
}
Upvotes: 1
Reputation: 9619
You can use something like this:
/!\ Warning: If you stop your curses program without call endwin()
before, the terminal used to launch the program will have a very strange behavior.
include <curses.h>
int main(int argc, char *argv[])
{
// init curses
Xinitscr(argc, argv);
// init time
time_t t = 0, t2;
time(&t2);
// main loop
while (1) {
if (t2 - t > 0)
{
time(&t);
clear();
mvprintw(1,1, "%u", (unsigned int)t);
refresh();
}
time(&t2);
}
// end curses mode
// warning: if you do not call this at the end of your program,
// your terminal won't be usable.
endwin();
return 0;
}
Upvotes: 0