2

I have created a macro that display a text and after that it flush stdout. The problems is how to force to clear old printed text if the text is more longer than the newer.

Example : If I try to print a string with 50 characters after that I need to overwrite all the text and rewrite text with 25 characters. All the time I have part of first text is always printed because the second is more shorter.

Also I need to insert \r at the end of each line, how to add in my macro?

#include <stdio.h>
#include <string.h>
// I need to add "\r" to macro instead of to add it for all string
#define MESSAGE( fmt, args...) \
    do { setbuf(stdout, NULL); fprintf(stdout, fmt, ## args); fflush(stdout); sleep(5); } while (0)

int main()
{
    MESSAGE( "the application is started successfully\r");
    MESSAGE( "the application will be stopped soon\r");
    MESSAGE( "app stopped: ok\n\r");
    return 0;
}

Result:

./test2
app stopped: ok will be stopped soonlly

The expected result:

./test2
app stopped: ok
developer
  • 4,744
  • 7
  • 40
  • 55
  • 1
    1) Use standard C `__VA_ARGS__`, not the legacy gcc extension. 2) Use a function! – too honest for this site Oct 28 '15 at 14:52
  • 1
    To add a `\r`, just add another `fprintf(stdout,"\r");` or an `fputc('\r',stdout);` – Jean-Baptiste Yunès Oct 28 '15 at 14:55
  • 2
    VT100 escape sequence `\x1b[2K` (erase the line where the cursor is) might be useful, depending on your shell or terminal. – MikeCAT Oct 28 '15 at 14:56
  • Possible duplicate of [How to overwrite stdout in C](http://stackoverflow.com/questions/656504/how-to-overwrite-stdout-in-c) – Bo Persson Oct 28 '15 at 15:17
  • @MikeCAT : thanks, I have resolved the problem with `\x1b[2K` – developer Oct 28 '15 at 15:43
  • @MikeCAT do you mind sharing the usage of `\x1b[2K`.how do you erase a line with that? – machine_1 Oct 28 '15 at 16:12
  • @machine_1 When you send the sequence to a VT100 compatible terminal, the characters on the line where the cursor is will be erased and become blank. – MikeCAT Oct 29 '15 at 01:27
  • The simple way is to use an 'escape' sequence to get back to the beginning of the text, then use an 'escape sequence to erase the text then use an escape sequence to get back to the beginning again, then use message() macro to display the new text – user3629249 Oct 29 '15 at 16:32
  • from: here are the details for that escape sequence: <<< K EL Erase line (default: from cursor to end of line). ESC [ 1 K: erase from start of line to cursor. ESC [ 2 K: erase whole line. >>> – user3629249 Oct 29 '15 at 16:37

1 Answers1

1

This is the solution:

#include <stdio.h>
#include <string.h>

#define MESSAGE( fmt, args...) \
    do { fprintf(stdout, fmt, ## args); fprintf(stdout, "\r"); fflush(stdout); sleep(1); fprintf(stdout, "\x1b[2K"); } while (0)

int main()
{
    MESSAGE( "the application is started successfully");
    MESSAGE( "the application will be stopped soon");
    MESSAGE( "app stopped: ok");
    return 0;
}
developer
  • 4,744
  • 7
  • 40
  • 55
  • 1
    How do you make sure `stdout` actually *is* a terminal understanding your control sequences? I'd strongly advise to use something like e.g. `curses` if you want anything beyond a normal stream of text. –  Oct 28 '15 at 16:07
  • on some OSs (I think MAC is an example) the '\r' will also cause the terminal to scroll to the next line – user3629249 Oct 29 '15 at 16:30