Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erase the current printed console line

People also ask

How do you clear a line in C++?

Erase the part of the line. If n is 0 or not specified, the command clears from the cursor to the end of the line. If n is 1, the command clears from the cursor to the beginning of the line. If n is 2, the entire line is cleared.

Which command is used to erase the whole line in Unix?

Press Ctrl + a to move the cursor to the beginning of the line and then Ctrl + k to delete to the end of line.


You can use VT100 escape codes. Most terminals, including xterm, are VT100 aware. For erasing a line, this is ^[[2K. In C this gives:

printf("\33[2K\r");

You can use a \r (carriage return) to return the cursor to the beginning of the line:

printf("hello");
printf("\rbye");

This will print bye on the same line. It won't erase the existing characters though, and because bye is shorter than hello, you will end up with byelo. To erase it you can make your new print longer to overwrite the extra characters:

printf("hello");
printf("\rbye  ");

Or, first erase it with a few spaces, then print your new string:

printf("hello");
printf("\r          ");
printf("\rbye");

That will print hello, then go to the beginning of the line and overwrite it with spaces, then go back to the beginning again and print bye.


Some worthwhile subtleties...

\33[2K erases the entire line your cursor is currently on

\033[A moves your cursor up one line, but in the same column i.e. not to the start of the line

\r brings your cursor to the beginning of the line (r is for carriage return N.B. carriage returns do not include a newline so cursor remains on the same line) but does not erase anything

In xterm specifically, I tried the replies mentioned above and the only way I found to erase the line and start again at the beginning is the sequence (from the comment above posted by @Stephan202 as well as @vlp and @mantal) \33[2K\r

On an implementation note, to get it to work properly for example in a countdown scenario since I wasn't using a new line character '\n' at the end of each fprintf(), so I had to fflush() the stream each time (to give you some context, I started xterm using a fork on a linux machine without redirecting stdout, I was just writing to the buffered FILE pointer fdfile with a non-blocking file descriptor I had sitting on the pseudo terminal address which in my case was /dev/pts/21):

fprintf(fdfile, "\33[2K\rT minus %d seconds...", i);
fflush(fdfile);

Note that I used both the \33[2K sequence to erase the line followed by the \r carriage return sequence to reposition the cursor at the beginning of the line. I had to fflush() after each fprintf() because I don't have a new line character at the end '\n'. The same result without needing fflush() would require the additional sequence to go up a line:

fprintf(fdfile, "\033[A\33[2K\rT minus %d seconds...\n", i);

Note that if you have something on the line immediately above the line you want to write on, it will get over-written with the first fprintf(). You would have to leave an extra line above to allow for the first movement up one line:

i = 3;
fprintf(fdfile, "\nText to keep\n");
fprintf(fdfile, "Text to erase****************************\n");
while(i > 0) { // 3 second countdown
    fprintf(fdfile, "\033[A\33[2KT\rT minus %d seconds...\n", i);
    i--;
    sleep(1);
}

You could delete the line using \b

printf("hello");
int i;
for (i=0; i<80; i++)
{
  printf("\b");
}
printf("bye");

Usually when you have a '\r' at the end of the string, only carriage return is printed without any newline. If you have the following:

printf("fooooo\r");
printf("bar");

the output will be:

barooo

One thing I can suggest (maybe a workaround) is to have a NULL terminated fixed size string that is initialized to all space characters, ending in a '\r' (every time before printing), and then use strcpy to copy your string into it (without the newline), so every subsequent print will overwrite the previous string. Something like this:

char str[MAX_LENGTH];        
// init str to all spaces, NULL terminated with character as '\r'
strcpy(str, my_string);       // copy my_string into str
str[strlen(my_string)] = ' '; // erase null termination char
str[MAX_LENGTH - 1] = '\r';
printf(str);

You can do error checking so that my_string is always atleast one less in length than str, but you get the basic idea.


i iterates through char array words. j keeps track of word length. "\b \b" erases word while backing over line.

#include<stdio.h>

int main()
{
    int i = 0, j = 0;

    char words[] = "Hello Bye";

    while(words[i]!='\0')
    {
        if(words[i] != ' ') {
            printf("%c", words[i]);
        fflush(stdout);
        }
        else {
            //system("ping -n 1 127.0.0.1>NUL");  //For Microsoft OS
            system("sleep 0.25");
            while(j-->0) {
                printf("\b \b");
            }
        }

        i++;
        j++;
    }

printf("\n");                   
return 0;
}