print to screen from c console application overwri

2019-08-01 09:50发布

问题:

I want to overwrite the current line in a c console program to achieve output like in the linux shell command "top". If possible the method should work under windows and linux.

while (i < 100) {
       i++;
       sprintf(cTmp, "%3d", i);
       puts(cTmp);
       if ((character = mygetch()) == 'q') {
          break;
       }
    }

I would like to overwrite the previous number in each iteration and if possible look if the user entered a character without pausing the loop. If the user presses the key 'q' the loop should stop immediately.

回答1:

To achieve this, you need to access the terminal. The easiest way to do this is with a library like ncurses. There seems to be a version that supports Windows as well.

With ncurses, you can give the coordinates for the string to output, like this:

mvprintw(row, col, "%s", text);


回答2:

You don't need ncurses if this is all you're doing. All you need to do is move the cursor to the beginning of the line and overwrite what's there, and make sure to flush the output buffer because stdout is usually line-buffered if it's hooked up to a terminal. Here's an example:

#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    int i;
    for (i = 0; ; ++i) {
        printf("\rIteration %d", i);
        fflush(stdout);
        usleep(250000);
    }
}

The carriage return character, '\r', moves the cursor to the beginning of the current line. If you want to do anything more fancy than this, use the ncurses library.

I don't know if this will work on Windows, the Windows console is somewhat odd compared to most other OSs.



回答3:

You should be able to use something like SetConsoleCursorPosition to manipulate the console cursor. Move the cursor to the beginning of the line, overwrite the entire line with space characters, and then move the cursor back to the beginning. You can even wrap this up in a "clear_line()" function for ease of use.

You can also use SetConsoleActiveScreenBuffer to do this. Instead of overwriting the current line, write into a second screen buffer. Once you have the second buffer completely filled in, make it the active buffer. Then, clear out the original screen buffer and use it for the next display frame, etc etc.