How do you clear the console screen in C?

442,077

Solution 1

Well, C doesn't understand the concept of screen. So any code would fail to be portable. Maybe take a look at conio.h or curses, according to your needs?

Portability is an issue, no matter what library is used.

Solution 2

printf("\e[1;1H\e[2J");

This function will work on ANSI terminals, demands POSIX. I assume there is a version that might also work on window's console, since it also supports ANSI escape sequences.

#include <unistd.h>

void clearScreen()
{
  const char *CLEAR_SCREEN_ANSI = "\e[1;1H\e[2J";
  write(STDOUT_FILENO, CLEAR_SCREEN_ANSI, 12);
}

There are some other alternatives, some of which don't move the cursor to {1,1}.

Solution 3

For portability, try this:

#ifdef _WIN32
#include <conio.h>
#else
#include <stdio.h>
#define clrscr() printf("\e[1;1H\e[2J")
#endif

Then simply call clrscr(). On Windows, it will use conio.h's clrscr(), and on Linux, it will use ANSI escape codes.

If you really want to do it "properly", you can eliminate the middlemen (conio, printf, etc.) and do it with just the low-level system tools (prepare for a massive code-dump):

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void ClearScreen()
{
  HANDLE                     hStdOut;
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  DWORD                      count;
  DWORD                      cellCount;
  COORD                      homeCoords = { 0, 0 };

  hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
  if (hStdOut == INVALID_HANDLE_VALUE) return;

  /* Get the number of cells in the current buffer */
  if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return;
  cellCount = csbi.dwSize.X *csbi.dwSize.Y;

  /* Fill the entire buffer with spaces */
  if (!FillConsoleOutputCharacter(
    hStdOut,
    (TCHAR) ' ',
    cellCount,
    homeCoords,
    &count
    )) return;

  /* Fill the entire buffer with the current colors and attributes */
  if (!FillConsoleOutputAttribute(
    hStdOut,
    csbi.wAttributes,
    cellCount,
    homeCoords,
    &count
    )) return;

  /* Move the cursor home */
  SetConsoleCursorPosition( hStdOut, homeCoords );
}

#else // !_WIN32
#include <unistd.h>
#include <term.h>

void ClearScreen()
{
  if (!cur_term)
  {
     int result;
     setupterm( NULL, STDOUT_FILENO, &result );
     if (result <= 0) return;
  }

   putp( tigetstr( "clear" ) );
}
#endif

Solution 4

A workaround tested on Windows(cmd.exe), Linux(Bash and zsh) and OS X(zsh):

#include <stdlib.h>

void clrscr()
{
    system("@cls||clear");
}

Solution 5

Using macros you can check if you're on Windows, Linux, Mac or Unix, and call the respective function depending on the current platform. Something as follows:

void clear(){
    #if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
        system("clear");
    #endif

    #if defined(_WIN32) || defined(_WIN64)
        system("cls");
    #endif
}
Share:
442,077
devurs
Author by

devurs

Updated on September 21, 2021

Comments

  • devurs
    devurs over 2 years

    Is there a "proper" way to clear the console window in C, besides using system("cls")?

  • N 1.1
    N 1.1 about 14 years
    +1 although i didnt ask, but this can be quite useful. And what can be done on unix to 'clear'?
  • Derrick Turk
    Derrick Turk about 14 years
    I +1'd you before reading your line about conio.h. Note that, too, is highly non-portable.
  • Billy ONeal
    Billy ONeal about 14 years
    Do note that this is not portable.
  • Billy ONeal
    Billy ONeal about 14 years
    The OP explicitly said this was NOT what he was looking for.
  • Mark Wilkins
    Mark Wilkins about 14 years
    @nvl: I only have windows machines at home, and takes about 15 usernames and passwords to log into work machines from here, so I can't test it right now. But I believe ncurses is the route for that (linux.die.net/man/3/ncurses).
  • mctylr
    mctylr about 14 years
    Huh?! Assuming the terminfo call was successful, and the terminal type is a smart (not 'dumb' or 'tty') then you might as well use a terminfo (or termcap) clear screen instruction (clear / cl), rather than pushing multiple newlines, which can be slow on larger X-Window terminals, particularly across networks.
  • devurs
    devurs about 14 years
    I'm not sure about conio.h, but it looks like curses takes care of the GUI in a more comprehensive way than I was initially imagining. I'll have to look into this. Thanks for the suggestion!
  • devurs
    devurs about 14 years
    I was actually thinking in terms of Unix-based systems - but this helps for Windows. Thanks!
  • Muthu Ganapathy Nathan
    Muthu Ganapathy Nathan over 12 years
    And it is not in c standard. Note that , OP mentioned Is there a "proper" way
  • Premature Optimization
    Premature Optimization over 11 years
    \n way immediately poses a next problem: what is min number of newlines has to be written to get everything scrolled out of terminal?
  • dodgy_coder
    dodgy_coder about 11 years
    Just to let you know, FWIW, this sequence as is didn't work for me in a windows cmd.exe console.
  • lurker
    lurker over 10 years
    For this kind of solution, a loop construct (while or for) would be a little more elegant. See for example: cprogramming.com/faq/cgi-bin/…
  • Shravan
    Shravan over 9 years
  • 0-0
    0-0 over 9 years
    Its not very bad as most compilers will correct it automatically. You are correct that it is wrong and shouldnt be used.
  • MofX
    MofX over 9 years
    "Yes I could have I guess. But why use a loop when I can copy-paste for the same effect?" Because copy'n'paste violates one of the most important rules in good programming: DRY - Don't repeat yourself
  • JD3
    JD3 about 9 years
    I have done as you suggested, and added a nice loop :)
  • user2284570
    user2284570 about 9 years
    @anon : This if for UNIX. Do you do the answer for DOS?
  • Keith Thompson
    Keith Thompson almost 9 years
    That prints 160 newlines and leaves the cursor at the bottom of the screen. It's actually possible to have a window taller than 160 lines.
  • Keith Thompson
    Keith Thompson almost 9 years
    How does it demand POSIX? I don't believe those escape sequences are specified by the POSIX standard.
  • Braden Best
    Braden Best over 8 years
    That doesn't work for me. What does work for me, though, is plain old "\e[2J". I know it's been like four years, but... Care to explain the difference? Or what the "\e[1;1H" is supposed to do?
  • Braden Best
    Braden Best over 8 years
    @PrematureOptimization Forty quadvigiseptanovatriheptasexgesillion, which we won't have CPUs capable of processing until we have a 2048-bit CPU with a bitchin bignum library. Sorry, you're out of luck. You're just gonna have to live with the fact that people who run their system using the side of the Empire State Building as a projection monitor with a fullscreen terminal running a 1pt font will get an ugly-looking "clear" effect. That's a rare edge case. Otherwise, ~100 lines should do the trick. (Xterm running its default font at fullscreen on a 1080p monitor is only 74 lines tall)
  • Braden Best
    Braden Best over 8 years
    test.c:(.text+0x31): undefined reference to 'clrscr' collect2: error: ld returned 1 exit status. With stdio.h and stdlib.h included. Not portable.
  • DrBeco
    DrBeco over 8 years
    1- Its monstruous; 2- The OP explicitly asked not to use it; 3- OP is asking for C language command, and system calls commands for other languages (said, bash, zsh, batch, etc.). Still +1 to try to make it portable. (I've tested on debian/linux and win7, even inverting the arguments. No need the @ also, because the command will not be on the screen after run)
  • Bryson S.
    Bryson S. about 8 years
    @Wilhelm This may not have been what the OP was looking for, but it was EXACTLY what I was looking for. Thanks.
  • Nic
    Nic about 8 years
    This code seems to work fine on Windows' CMD, at least in Win10.
  • Geremia
    Geremia over 7 years
    I get a "non-ISO-standard escape sequence, '\e'" when using this with C11.
  • Geremia
    Geremia over 7 years
    Using this I didn't get ISO compatibility errors: \033[2J\033[1;1H
  • Manoel Vilela
    Manoel Vilela over 6 years
    Actually this is really nice. +1 for pointing the "portable" way using ANSI escapes with the horrible but useful clrscr() from conio.h.
  • Manoel Vilela
    Manoel Vilela over 6 years
    Just for saying: clrscr() is not available on conio.h implementation of mingw compiler
  • MD XF
    MD XF over 6 years
    Windows' command prompt (Windows 98 through Windows 7) does not support ANSI escapes. It seems that they do in Windows 10 and so presumably Windows 8 as noted by QPaysTaxes.
  • Arne Vogel
    Arne Vogel almost 6 years
    Nit: Don't use printf(string);, use puts(string); instead. The former may have UB if string contains a percent sign (even though that is not the case here, I recommend making it a habit).
  • Pranav Chaudhary
    Pranav Chaudhary almost 5 years
    Why does that regex work? Can someone please post a link that explains this?
  • cmaster - reinstate monica
    cmaster - reinstate monica about 4 years
    Seconding Keith Thompson, I get already 159 lines on an old, vertical full HD monitor. The moment I'm upgrading to 4k, there will be more than 160 lines... General point: Never assume "oh, this will suffice in all cases". Cause it won't. Whenever you assume this, you are producing a bug that's just waiting to happen. Always actually determine your need, or choose methods that always do the right thing. (Same with buffer lengths, string lengths, etc. pp.)
  • Dosisod
    Dosisod almost 4 years
    \033[x;yH will re-position the cursor to row x, column y. If x is 1, it can may be omitted: \033[;yH. en.wikipedia.org/wiki/…
  • jdt
    jdt over 2 years
    _WIN32 will be defined on Windows even if you build for 64-bit.