Das Escape-Zeichen "\ b" "Rücktaste": unerwartetes Verhalten?

101

Also lese ich endlich K & R durch und habe auf den ersten Seiten etwas gelernt, dass es einen Backspace-Escape-Charakter gibt \b.

Also probiere ich es aus und es gibt ein sehr merkwürdiges Verhalten:

#include <stdio.h>

main ()
{
    printf("hello worl\b\bd\n");
}

Die Ausgabe ist

hello wodl

Kann jemand das erklären?

OregonTrail
quelle

Antworten:

145

Ihr Ergebnis hängt davon ab, auf welcher Art von Terminal- oder Konsolenprogramm Sie sich befinden. Bei den meisten \bhandelt es sich jedoch um eine zerstörungsfreie Rücktaste. Der Cursor wird rückwärts bewegt, aber nicht gelöscht, was sich dort befindet.

Für den hello worlTeil wird also der Code ausgegeben

Hallo Welt
          ^

... (wo ^zeigt, wo sich der Cursor befindet) Dann werden zwei \bZeichen ausgegeben, die den Cursor zwei Stellen rückwärts bewegen, ohne ihn zu löschen (auf Ihrem Terminal):

Hallo Welt
        ^

Beachten Sie, dass sich der Cursor jetzt auf dem befindet r. Dann gibt es aus d, was das überschreibt rund uns gibt:

Hallo Wodl
         ^

Schließlich wird \nausgegeben, was eine zerstörungsfreie neue Zeile ist (wiederum auf den meisten Terminals, einschließlich anscheinend Ihrer), sodass die lunverändert bleibt und der Cursor an den Anfang der nächsten Zeile bewegt wird.

TJ Crowder
quelle
1
Wenn es nicht gelöscht wird, warum ist dann das "r" weg?
Cesoid
1
@cesoid: "Ihr Ergebnis hängt davon ab, auf welcher Art von Terminal- oder Konsolenprogramm Sie sich befinden"
TJ Crowder
Es ist nur so, dass Ihr Beispiel nicht zur Ausgabe passt, also ist es kein Beispiel für eine mögliche Erklärung.
Cesoid
5
@cesoid Das rwird durch ersetzt d. Die Erklärung passt immer noch.
Syockit
1
@cesoid: Interessant über das Terminal. In Windows werden die Terminals cmd.exeund command.comnicht immer eingefügt (Sie können das Verhalten mit der Taste Ins umschalten). Ich war überrascht, dass Gnome Terminal auf meinem Hauptcomputer * nix immer eingefügt wird und nicht einmal eine Präferenz dafür zu haben scheint, geschweige denn basierend auf der Ins-Taste umzuschalten. Das habe ich noch nie bemerkt. Klar, ich will fast nie überschreiben. :-)
TJ Crowder
122
..........
^ <= Zeiger auf "Druckkopf"
            /* part1 */
            printf("hello worl");
Hallo Welt
          ^ <= Zeiger auf "Druckkopf"
            /* part2 */
            printf("\b");
Hallo Welt
         ^ <= Zeiger auf "Druckkopf"
            /* part3 */
            printf("\b");
Hallo Welt
        ^ <= Zeiger auf "Druckkopf"
            /* part4 */
            printf("d\n");
Hallo Wodl

^ <= Zeiger auf "Druckkopf" in der nächsten Zeile
pmg
quelle
Wenn sich der Cursor nach Teil 4 auf dem Buchstaben 'l' befindet, sollte er dann nicht durch den Buchstaben '\ n' ersetzt werden? (was zu "Hallo wor" führt)
lucas_turci
@lucas_turci: die sache ist, dass der '\n'keine darstellung auf dem bildschirm hat. Was schon da ist, bleibt gleich; nicht durch ein Leerzeichen oder eine andere Zeichendarstellung ersetzt.
PMG
44

Wenn Sie eine zerstörerische Rücktaste wünschen, benötigen Sie so etwas wie

"\b \b"

dh eine Rücktaste, eine Leertaste und eine andere Rücktaste.

Peter K.
quelle
Dies lässt immer noch den Raumcharakter da, nicht wahr?
Pacerier
Nun ja, aber das nachfolgende \bbedeutet, dass das nächste Ausgabezeichen es überschreibt.
Peter K.
1
Was ist, wenn es kein nachfolgendes Zeichen gibt?
Pacerier
Dann ist es egal, oder?
Peter K.
1
Hmm. Sofern Ihr Gerät nicht die Option "Letztes Zeichen löschen" (z. B. DEL / 0x7f) implementiert , bin ich ratlos.
Peter K.
8

Nicht zu schwer zu erklären ... Dies ist wie Tippen hello worl, zweimaliges Drücken der linken Pfeiltaste, zweimaliges Drücken dund Drücken der Abwärtspfeiltaste.

Zumindest schließe ich so, dass Ihr Terminal die \bund \n-Codes interpretiert .

Leiten Sie die Ausgabe in eine Datei um und ich wette, Sie erhalten etwas ganz anderes. Möglicherweise müssen Sie sich jedoch die Bytes der Datei ansehen, um den Unterschied festzustellen.

[bearbeiten]

Um ein bisschen printfnäher darauf einzugehen, gibt dies eine Folge von Bytes aus: hello worl^H^Hd^Jwobei ^Hdas ASCII-Zeichen Nr. 8 und ^Jdas ASCII-Zeichen Nr. 10 sind. Was Sie auf Ihrem Bildschirm sehen, hängt davon ab, wie Ihr Terminal diese Steuercodes interpretiert.

Nemo
quelle
1

Verwenden Sie nach jedem Zeichen eine einzelne Rücktaste printf("hello wor\bl\bd\n");

Dorothea
quelle
"Hallo Wod \ n"? Was bedeutet das?
Elias Hasle