Question Details

No question body available.

Tags

c terminal console

Answers (3)

Accepted Answer Available
Accepted Answer
July 23, 2025 Score: 6 Rep: 192,807 Quality: Expert Completeness: 100%

What is the "cleanest" way to clear the console in C

There is no universal way to do this in C, because C itself has no concept of "screen" or "console". Any mechanism you use will need to be specific to your particular console device. There are libraries that can abstract this for you. (ncurses, for example, though this particular one may be a little tricky on Windows.)

Since you're writing for Windows, you have access to the Windows Console API for controlling the console. HOWEVER, Microsoft now recommends what it calls "virtual terminal sequences", but which most others call "ANSI escape sequences". Or you could join me in my rebellious ways, and call them "ANSI terminal control sequences". This approach involves writing special byte sequences to the console that it interprets as commands rather than as data to display. To use this mechanism to clear the console in which your program is running, you could:

fputs("\033[2J", stdout);
fflush(stdout);

I guarantee that that is faster than calling the system() function to execute a command in the console. Note that I chose fputs() over puts(), printf(), and other alternatives intentionally. Unlike puts(), it does not append a newline, and it has less overhead than the printf() family of functions.

HOWEVER,

  1. The flicker you observe is surely the result of clearing the screen in the first place, especially in combination with the time it takes to draw / print the next frame afterward. Clearing the screen faster will not be nearly as helpful as drawing the next frame faster will be.

  2. I suspect that you're conflating two distinct effects: clearing the console and moving the cursor to the top left position. These are not necessarily associated with each other. Indeed, the code fragment above does only the clearing, not the cursor repositioning.

  3. Once you understand the separation between cursor positioning and the content displayed on the console, it should become evident that you don't necessarily have to clear the screen (separately) at all, if you're prepared instead to simply overwrite its full contents with the next frame.

  4. The console is pretty slow overall. Maybe not too slow for what you want to do if you are careful about how you do it, but do be prepared for the possibility that it just isn't fast enough for you no matter what you do.

If you want to proceed with rolling your own console-based renderer, then here are some suggestions:

  1. Draw each new frame directly on top of the previous one, without clearing the screen between. To facilitate that, you can move the cursor to the top, left of the console window with a different terminal-control sequence:

    fputs("\033[1;1H", stdout);
    
  2. That means that for every frame, you must rewrite every character in your display area that may have changed (but only once, not twice as clearing first would require for at least some positions). There are other control sequences that can help with that by positioning the cursor and clearing all or part of the current line, or to the end of the screen.

  3. Manipulate the I/O buffer size and buffering mode for the console so that you can render a whole frame at a time to the buffer, then flush it out to the console all at once. Be sure to allow space in the buffer for any embedded terminal-control sequences you plan.

    For example, you might:

    #include 

    #define DISPLAYWIDTH 80 #define DISPLAYHEIGHT 25 // Provides for 16 bytes of control data per line, plus an extra 16: #define BUFFERSIZE (DISPLAYHEIGHT * (DISPLAYWIDTH + 16) + 16)

    // ...

    int main(void) { char screenbuf[BUFFERSIZE];

    setvbuf(stdout, screenbuf, IOFBF, BUFFERSIZE); // ...

    That sets fully-buffered mode, with the expectation that you will never fill the buffer completely. It anticipates that you will instead use fflush(stdout) to flush the buffer contents to the console once you have used stdio functions to write a complete frame.

    You could instead write directly into the buffer with sprintf() and / or string-manipulation functions, then print the whole string at once with fputs() (and flush), but then you introduce a needless extra buffer, and for each frame, a copy from the data buffer to the I/O buffer. On the other hand, that might make it easier to do the rendering you want to do.

  4. You probably want to hide the cursor. There's a control sequence for that: "\033[?25l". (That's a lowercase 'L' at the end.)

July 24, 2025 Score: 3 Rep: 483 Quality: Medium Completeness: 80%

It sounds like you would want to use the Alternate Screen Buffer mode.

To start: \033[?1049h
To end: \033[?1049l
See also: https://stackoverflow.com/a/11024208/23455963

In the normal mode, the terminal has a fixed width and a potentially infinite height. Writing past the width may or may not result in wrapping, writing past the length will result in a height increase. To still view everything, the user can scroll the terminal.

When you clean the screen some terminals clear the scrollback, some scroll further until every line moves out of view. The user can still scroll back. When you add lines to the bottom of the screen to change the "frame" and the user scrolls back, he will se parts of previous "frames". That sounds ugly.

You essentially want to treat the terminal as a fixed width x height screen. This is exactly what the Alternate Screen Buffer mode is. After switching into it, the screen will already been clear and the cursor starts in the upper left corner. There won't be any wrapping and no scrollback functionality. This also has the advantage that once your program quits and switches back to normal mode (Don't forget to do that, otherwise that will annoy users.) the terminal will look like it did before your program switched to the alternate mode. This way the user won't loose output from other programs.

Assuming you have a XTerm compatible terminal you read about it here: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer

You can also take inspiration of other programs behaviour like less a pager and famously mc. They only draw over the parts that need change, instead of redrawing everything. As others have noted may use ncurses

July 28, 2025 Score: 1 Rep: 790 Quality: Low Completeness: 80%

I've made this function to clear the terminal (based on Microsoft's clearing screen examples), that uses ANSI escape codes to clear the terminal, which are supported by most terminals (including Windows terminals):

#include 
#ifdef WIN32
 #include 
#endif

void clear
terminal(){ #ifdef WIN32 HANDLE hStdOut;

hStdOut = GetStdHandle(STD
OUTPUTHANDLE);

// Fetch existing console mode so we correctly add a flag and not turn off others DWORD mode = 0; if (!GetConsoleMode(hStdOut, &mode)) { return; }

// Hold original mode to restore on exit to be cooperative with other command-line apps. const DWORD originalMode = mode; mode |= ENABLE
VIRTUALTERMINALPROCESSING;

// Try to set the mode. if (!SetConsoleMode(hStdOut, mode)) { return; } #endif

// Write the sequence for clearing the display: // \x1B[2J - Clears the visible window // \x1B[3J - Clears the scroll back // \x1B[1;1H - Move cursor back to its home coordinates (top left) fputs("\x1B[2J\x1B[3J\x1B[1;1H", stdout); fflush(stdout);

#ifdef _WIN32 // Restore the mode on the way out to be nice to other command-line applications. SetConsoleMode(hStdOut, originalMode); #endif }