2

Is it possible to print out (in C) a line of text to the console on a Linux OS containing a variable so that when the variable changes, it changes the printed line instead of printing a new line? For example, if I have the following C code:

void main()
{
     int i;
     for(i=1;i<=10;i++){
        printf("%d\n",i);
        sleep(5);
     }
}

As is, that would print ten lines. But I want to print one line that updates itself to show the value of i when it changes.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
cHam
  • 2,624
  • 7
  • 26
  • 28

3 Answers3

6

On Linux, void main(void) is undefined behaviour; the return type is int — no exceptions. On Windows, the rules are different; on Unix, they're simple — main() returns int!

Use '\r' carriage return and fflush():

#include <stdio.h>

int main(void)
{
     int i;
     for (i = 1; i <= 10; i++)
     {
        printf("\r%d", i);
        fflush(stdout);
        sleep(5);
     }
     putchar('\n');
     return 0;
}

No need to use the curses library unless your display needs get more complex.

Note: if you are counting down (or the length of the current row of output decreases for any reason), you need to make sure you write blanks over previously displayed data. So, for example, you might need the format string "\r%-4d" to count from 9999 to 0 without leaving unwanted digits on display.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Nice. I've used `"\r%d "` in the past with the extra space to erase. – chux - Reinstate Monica Dec 30 '13 at 03:21
  • 2
    That'll work nicely as long as the generated strings (numbers) are strictly decreasing. Counters that go from 81.11 MB to 81 MB and back to 80.88 MB could suffer more, but the key point is to ensure that extra characters are erased, every time. (Said counters annoy me; they should present 81.00 MB in the middle; if it is relevant to report 2 dp, do it consistently!) – Jonathan Leffler Dec 30 '13 at 03:29
5

Something like the following should do the job (taken / modified from How to update a printed message in terminal without reprinting (Linux))

int main(int argc, char *argv[]) {
  for(int i=1;i<=10;++i) {
    printf("\r[%3d%%]",i);
    fflush(0);
    sleep(5);
  }
  printf("\n");
}
Community
  • 1
  • 1
cronburg
  • 892
  • 1
  • 8
  • 24
-1

Not exactly sure what you are up to, but maybe writing the content of your variable into a temporary file and using watch(1) to visualize it is an option?

Karol Babioch
  • 666
  • 8
  • 16
  • 1
    Welcome to Stack Overflow. Please read the [About] page soon. I'm not one of the down-voters, but I suspect the reason you got down-voted is that you've not provided any link to the `watch` program (for example, [_watch(1)_](http://linux.die.net/man/1/watch)), nor given an outline explanation of what it does. For example, a gotcha would be that if the data in the program was written to a file, the program would have to `fflush()` the file each time it wrote to make sure there was a difference for `watch` to see. – Jonathan Leffler Dec 30 '13 at 01:38