Erase the current printed console line

Viewed 190344

How can I erase the current printed console line in C? I am working on a Linux system. For example -

printf("hello");
printf("bye");

I want to print bye on the same line in place of hello.

13 Answers

under windows 10 one can use VT100 style by activating the VT100 mode in the current console to use escape sequences as follow :

#include <windows.h>
#include <iostream>

#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#define DISABLE_NEWLINE_AUTO_RETURN  0x0008

int main(){

  // enabling VT100 style in current console
  DWORD l_mode;
  HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  GetConsoleMode(hStdout,&l_mode)
  SetConsoleMode( hStdout, l_mode |
            ENABLE_VIRTUAL_TERMINAL_PROCESSING |
            DISABLE_NEWLINE_AUTO_RETURN );

  // create a waiting loop with changing text every seconds
  while(true) {
    // erase current line and go to line begining 
    std::cout << "\x1B[2K\r";
    std::cout << "wait a second .";
    Sleep(1);
    std::cout << "\x1B[2K\r";
    std::cout << "wait a second ..";
    Sleep(1);
    std::cout << "\x1B[2K\r";
    std::cout << "wait a second ...";
    Sleep(1);
    std::cout << "\x1B[2K\r";
    std::cout << "wait a second ....";
 }

}

see following link : windows VT100

Just found this old thread, looking for some kind of escape sequence to blank the actual line.

It's quite funny no one came to the idea (or I have missed it) that printf returns the number of characters written. So just print '\r' + as many blank characters as printf returned and you will exactly blank the previuosly written text.

int BlankBytes(int Bytes)
{
                char strBlankStr[16];

                sprintf(strBlankStr, "\r%%%is\r", Bytes);
                printf(strBlankStr,"");

                return 0;
}

int main(void)
{
                int iBytesWritten;
                double lfSomeDouble = 150.0;

                iBytesWritten = printf("test text %lf", lfSomeDouble);

                BlankBytes(iBytesWritten);

                return 0;
}

As I cant use VT100, it seems I have to stick with that solution

echo -e "hello\c" ;sleep 1 ; echo -e "\rbye  "

What the above command will do :

  1. It will print hello and the cursor will remain at "o" (using \c)

  2. Then it will wait for 1 sec (sleep 1)

  3. Then it will replace hello with bye.(using \r)

NOTE : Using ";", We can run multiple command in a single go.

For me, this code, work well for serial console window with arduino on Tera Term VT console:

SEROUT.print("\e[A\r\n\e[2K");
SEROUT.print('>');

I use '>' because on my console command i type command after '>'

Others have already answered OP's question. Here is an answer for those wondering why carriage return behaves the way it does on their Linux machine -

The behavior of the carriage return character seems to be platform-dependent.

From section '5.2.2 Character display semantics' of the C11 standard:

\r (carriage return) Moves the active position to the initial position of the current line.

From section '3.86 Carriage-Return Character (< carriage-return>)' of the POSIX standard (https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html):

A character that in the output stream indicates that printing should start at the beginning of the same physical line in which the carriage-return occurred. It is the character designated by '\r' in the C language. It is unspecified whether this character is the exact sequence transmitted to an output device by the system to accomplish the movement to the beginning of the line.

It does not state whether carriage return is supposed to erase (=> populate with NUL characters) the entire line or not. My guess is that it is NOT supposed to erase.

However, on my Linux machine (tried on both x86_64 and ARM32), what I observed is that the carriage return character moved the cursor to the beginning of the current line and also populated the line with '\0' characters (NUL characters). In order to notice those NUL characters, you might have to call the write system call directly from your code instead of calling via glibc printf.

Let's take the following code snippet as an example:

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

Building and running this on beaglebone black (32-bit ARM) bash terminal:

ubuntu@arm:~$ ./a.out 
byeubuntu@arm:~$ 

strace output on write syscall:

bye)               = 9 9hello
+++ exited with 4 +++
Related