Löschen Sie die aktuelle gedruckte Konsolenzeile

Lesezeit: 6 Minuten

Wie kann ich die aktuelle gedruckte Konsolenzeile in C löschen? Ich arbeite auf einem Linux-System. Zum Beispiel –

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

Ich möchte in derselben Zeile Tschüss anstelle von Hallo ausgeben.

  • Die ncurses-Bibliothek wird dies wahrscheinlich tun. Ich kenne es nicht gut genug, um eine Antwort zu geben, aber hier sind Links zu Dokumente und eine verwandte Frage. Dieser Kommentar basiert auf der Antwort von Wil Shipley aus dem Jahr 2009, die gelöscht werden kann.

    – Tom Zych

    17. Januar 2016 um 14:54 Uhr


Benutzeravatar von mouviciel
mouviciel

Sie können verwenden VT100-Escape-Codes. Die meisten Terminals, einschließlich xterm, unterstützen VT100. Zum Löschen einer Zeile ist dies ^[[2K. In C this gives:

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

  • This does not reset the cursor to the beginning of the line (in my terminal, at least), so \r is still required. Note that the use of %c is not necessary. Alternative: printf("\33[2K\r");

    – Stephan202

    Oct 2, 2009 at 9:46

  • Just a little note that ANSI formatting isn’t supported in Windows (ANSI escape code). But it’s still possible to use printf("\r ");.

    – CocoaBob

    Mar 14, 2014 at 16:13


  • @CocoaBob That has changed as of Windows 10 update TH2.

    – Hydranix

    Jun 3, 2016 at 10:57

  • it’s not working on Windows before Windows 10

    – phuclv

    Jul 8, 2016 at 3:57

  • @LưuVĩnhPhúc – Question ends with: I am working on a linux system

    – mouviciel

    Jul 8, 2016 at 6:46

J-a-n-u-s's user avatar
J-a-n-u-s

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);
}

  • \r is short for “carriage return”, not “rewind”, and is a relic of good old typewriters, which had separate operations for “move cursor back to first column” (\r) and “advance page to next row” (\n).

    – ijustlovemath

    Nov 26, 2017 at 20:21

  • \33[2K is a way to go! Best problem solution for me. Also works on Windows ConEmu

    – Grzegorz

    Jul 1, 2018 at 0:12

  • For some reason, all these wonderful answers just don’t work for me when I run a simple C executable on my MacOS in Terminal (bash, zsh whatever). I get all kinds of strange behaviours, and weird characters (or nothing at all) printed, but never the clear-line-than-print-over-it etc.

    – Motti Shneor

    Oct 4, 2020 at 18:05


  • \033[A moves your cursor up one line, but in the same column i.e. not to the start of the line” I don’t think this works, and I don’t see the code listed in the reference

    – deWalker

    May 22 at 21:33


Andre Miller's user avatar
Andre Miller

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.

  • “It won’t erase the existing characters though, and because bye is shorter than hello, you will end up with byelo.” -> Maybe it is platform dependent? Check my answer: stackoverflow.com/a/68294831/4726668

    – ZeZNiQ

    Jul 8, 2021 at 2:20

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 zu allen Leerzeichen, NULL beendet mit Zeichen als '\r' strcpy(str, my_string);  // my_string in str kopieren str[strlen(my_string)] = ' ';  // Null-Terminierungszeichen löschen str[MAX_LENGTH - 1] = '\r';  printf(str);

Sie können damit eine Fehlerprüfung durchführen my_string ist immer mindestens um eins kürzer als straber Sie verstehen die Grundidee.

Benutzeravatar von bstpierre
bstpierre

i iteriert durch char-Array-Wörter. j verfolgt die Wortlänge. "\b \b" löscht Wort beim Rückwärtsfahren über die Zeile.

#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;
}

Benutzeravatar von mantal
mantal

Dieses Skript ist für Ihr Beispiel fest codiert.

#include  int main () { //Einige Eingaben schreiben fputs("hello\n",stdout);  //eine Sekunde warten, um die Zeile über sleep(1) zu ändern;  //Zeile entfernen fputs("\033[A\033[2K",stdout);
    rewind(stdout);

    //write new line
    fputs("bye\n",stdout);

    return 0;
}

Click here for source.

1420020cookie-checkLöschen Sie die aktuelle gedruckte Konsolenzeile

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy