Clear the Screen – Solution

The task for this month’s Exercise is to clear the screen. I pray you didn’t arrive at a solution that outputs multiple blank lines. No, you must use the ANSI codes offered in the exercise post to manipulate the cursor and wipe clean the screen. Or you could cheat, which is what I did.

I didn’t really cheat. No, I obtained guidance.

The clear command wipes the terminal window screen and homes the cursor. It does so by outputting text, the same ANSI codes that appear in the table presented in the challenge post. I redirected this output to a file, then used the hexdump utility to view its contents:

00000000  1b 5b 48 1b 5b 32 4a 1b  5b 33 4a                 |.[H.[2J.[3J|
0000000b

Hex code 1b is the escape character, ESC on the keyboard and \e in C. In the dump, I see three ANSI commands:

\e[H – home the cursor
\e[2J – erase the entire screen
\e[3J – erase saved lines

This is the output I generated in my cls() function for my solution:

2024_07-Exercise.c

#include <stdio.h>

void cls(void)
{
    printf("\e[H\e[2J\e[3J");
}

int main()
{
    printf("Prepare to clear the screen!");
    getchar();
    cls();

    return 0;
}

Even so, and yes I kinda did cheat, you can get by with the following printf() statement instead:

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

These ANSI codes also clear the screen, but they don’t erase saved lines. I’m not clear on what the difference is, so either way if you used these codes to clear the screen, you passed the challenge.

4 thoughts on “Clear the Screen – Solution

  1. With regards to my solution to this challenge I can, I think, comment on the difference between "\x1B[2J" and "\x1B[3J".

    During my experiments I found that "\x1B[2J" doesnʼt really clear the screen. Rather, it causes windows to scroll down until any previous contents are no longer visible—just like what `clear` does.

    This is where "\x1B[3J" comes in: after this sequence is issued, all scrollback data is removed as well (and scrollbars, if any were visible, should go away).

    To completely clear the screen, both seem to be necessary. With the caveat that "\x1B[3J" (also referred to as ‘extended capability E3’) was added at a later time and may not be supported all Terminal emulators.

    Support for E3 can be checked by querying the systems ‘terminfo database’—either by invoking tigetstr("E3"); (and testing for a non-NULL return value) or even in the shell by relying on infocmp to list all terminfo entries:

      $ infocmp -x | grep -o -P '(?<=E3=)[^,]*'

  2. I actually prefer the behaviour of the GNOME terminal I use which is to not erase old stuff. You know when you screw up a piece of paper, throw it away and then realise you need it after all? Well it’s like that!

    I misread tigetstr as tigerstr. Presumably a function to print a string in alternating orange and black.

    Those ANSI codes aren’t very friendly, either to write or read. A few times I’ve done something like this:

    #define RED “\x1B[31m”
    #define GRN “\x1B[32m”
    #define RESET “\x1B[0m”
    .
    .
    .
    printf(GRN “%c” RESET, “this is green”);
    printf(“%c”, “this is the default colo(u)r”);
    printf(RED “%c” RESET, “this is red”);

    It would be easy to put them all in a separate library for repeated use. No doubt someone has already thought of that.

    I assume curses can do this with a single function. Maybe Dan “Curses Expert” Gookin will tell us . . .

  3. I agree. This behavior, to just scroll down/not to really clear the terminal, is sometimes advantageous. Also, whenever I use ANSI escapes (in a Bash script or wherever) I too like to hide those nasty escape sequences behind constants/macros.

    That being said: in production-strength code it would—as I understand it—probably be best to rely on the aforementioned tigetstr() function to query the systems ‘terminfo database’⁽¹⁾ for the “correct” escape sequences (to effect certain terminal behaviors).

    Under Linux, the terminfo database can, for example, be queried by relying on the infocmp command-line tool:

      # Sequence to reset fg/bg color to default values?
      $ infocmp -x | grep -o -P ‘(?<=op=)[^,]*'
      \E[39;49m

      # Sequence to clear the terminal by scrolling everything up?
      $ infocmp -x | grep -o -P '(?<=clear=)[^,]*'
      \E[H\E[2J

      # Sequence to clear the terminals' backlog?
      $ infocmp -x | grep -o -P '(?<=E3=)[^,]*'
      \E[3J

    On the other hand: since nobody any longer has real terminals, most—if not all—of these sequences should probably be safe even if one does not go to the hassle of querying them beforehand.

    ⁽¹⁾ See terminfo.5.html for a nice reference.

  4. Chris, the NCurses method for color output is just as whacky. You must define a color pair, then apply that pair to text. The colors can also be defined, depending on the terminal definition. Doing the macros is a great idea!

Leave a Reply