Il carattere di escape "backspace" "\ b": comportamento inaspettato?


101

Così sto finalmente la lettura attraverso K & R , e ho imparato qualcosa entro le prime pagine, che v'è un carattere di escape backspace, \b.

Quindi vado a provarlo e c'è un comportamento molto strano:

#include <stdio.h>

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

L'output è

hello wodl

Qualcuno può spiegarlo?

Risposte:


145

Il risultato varierà a seconda del tipo di terminale o di programma della console in uso, ma sì, nella maggior parte dei casi \bè un backspace non distruttivo . Sposta il cursore indietro, ma non cancella il contenuto.

Quindi per la hello worlparte, il codice esce

ciao worl
          ^

... (dove ^mostra dove si trova il cursore) Quindi emette due \bcaratteri che sposta il cursore indietro di due posizioni senza cancellare (sul tuo terminale):

ciao worl
        ^

Nota che il cursore è ora sul file r. Quindi emette d, che sovrascrive re ci dà:

ciao wodl
         ^

Infine, viene emesso \n, che è una nuova riga non distruttiva (di nuovo, sulla maggior parte dei terminali, incluso apparentemente il tuo), quindi lrimane invariato e il cursore viene spostato all'inizio della riga successiva.


1
Se non si cancella, perché la "r" è sparita?
cesoid

1
@cesoid: "Il risultato varierà a seconda del tipo di terminale o programma della console in uso"
TJ Crowder

È solo che il tuo esempio non si adatta all'output, quindi non è un esempio di una possibile spiegazione.
cesoid

5
@cesoid Il rè sostituito con d. La spiegazione si adatta ancora.
syockit

1
@cesoid: Interessante per il terminale. In Windows, i terminali cmd.exee command.comnon si inseriscono sempre (è possibile utilizzare il tasto Ins per attivare o disattivare il comportamento). Sono stato sorpreso di scoprire che Gnome Terminal sul mio computer * nix principale si inserisce sempre, non sembra nemmeno avere una preferenza per il suo interruttore in base al tasto Ins. Non l'avevo mai notato prima. Chiaramente non voglio quasi mai scrivere. :-)
TJ Crowder

122
..........
^ <= puntatore a "testina di stampa"
            /* part1 */
            printf("hello worl");
ciao worl
          ^ <= puntatore a "testina di stampa"
            /* part2 */
            printf("\b");
ciao worl
         ^ <= puntatore a "testina di stampa"
            /* part3 */
            printf("\b");
ciao worl
        ^ <= puntatore a "testina di stampa"
            /* part4 */
            printf("d\n");
ciao wodl

^ <= puntatore a "testina di stampa" nella riga successiva

Se il cursore dopo la parte 4 si trova sulla lettera "l", non dovrebbe essere sostituito con la "\ n"? (risultante in "hello wor")
lucas_turci

@lucas_turci: il fatto è che '\n'non ha una rappresentazione sullo schermo. Ciò che è già lì rimane lo stesso; non sostituito da uno spazio o da qualsiasi altra rappresentazione di carattere.
pmg

44

Se vuoi un backspace distruttivo, avrai bisogno di qualcosa di simile

"\b \b"

cioè un backspace, uno spazio e un altro backspace.


Questo lascia ancora il carattere spaziale, non è vero?
Pacerier

Ebbene, sì, ma il successivo \bsignificherà che il carattere di output successivo lo sovrascriverà.
Peter K.

1
E se non ci fosse un personaggio successivo?
Pacerier

Allora non importa, vero?
Peter K.

1
Hmm. A meno che il tuo dispositivo non implementi un'opzione "cancella l'ultimo carattere" (ad esempio DEL / 0x7f), sono perplesso.
Peter K.

8

Non è troppo difficile da spiegare ... È come digitare hello worl, premere due volte il tasto freccia sinistra, digitare de premere il tasto freccia giù.

Almeno, è così che deduco che il tuo terminale stia interpretando i codici \be \n.

Reindirizza l'output su un file e scommetto che otterrai qualcos'altro completamente. Anche se potrebbe essere necessario guardare i byte del file per vedere la differenza.

[modificare]

Per elaborare un po ', questo printfemette una sequenza di byte:, hello worl^H^Hd^Jdove ^Hè il carattere ASCII # 8 ed ^Jè il carattere ASCII # 10. Quello che vedi sullo schermo dipende da come il tuo terminale interpreta quei codici di controllo.


1

Usa un singolo backspace dopo ogni carattere printf("hello wor\bl\bd\n");


"ciao wod \ n"? Cosa significa?
Elias Hasle
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.