El carácter de escape "retroceso" '\ b': ¿comportamiento inesperado?

101

Así que finalmente estoy leyendo a través de K & R , y aprendí algo dentro de las primeras páginas, que hay un carácter de escape de retroceso, \b.

Así que voy a probarlo, y hay un comportamiento muy extraño:

#include <stdio.h>

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

La salida es

hello wodl

¿Alguien puede explicar esto?

OregonTrail
fuente

Respuestas:

145

Su resultado variará dependiendo del tipo de terminal o programa de consola en el que se encuentre, pero sí, en la mayoría \bhay un retroceso no destructivo . Mueve el cursor hacia atrás, pero no borra lo que está allí.

Entonces, para la hello worlparte, el código genera

hola mundo
          ^

... (donde ^muestra dónde está el cursor) Luego genera dos \bcaracteres que mueven el cursor hacia atrás dos lugares sin borrar (en su terminal):

hola mundo
        ^

Tenga en cuenta que el cursor ahora está en r. Luego sale d, que sobrescribe el ry nos da:

hola wodl
         ^

Finalmente, genera \n, que es una nueva línea no destructiva (nuevamente, en la mayoría de las terminales, incluida aparentemente la suya), por lo que lse deja sin cambios y el cursor se mueve al comienzo de la siguiente línea.

TJ Crowder
fuente
1
Si no se borra, ¿por qué desapareció la "r"?
cesoide
1
@cesoid: "Su resultado variará dependiendo del tipo de terminal o programa de consola en el que se encuentre"
TJ Crowder
Es solo que su ejemplo no se ajusta a la salida, por lo que no es un ejemplo de una posible explicación.
cesoide
5
@cesoid El rse reemplaza por d. La explicación aún encaja.
syockit
1
@cesoid: Interesante sobre la terminal. En Windows, los terminales cmd.exey command.comno siempre se insertan (puede usar la tecla Ins para alternar el comportamiento). Me sorprendió descubrir que Gnome Terminal en mi computadora principal * nix siempre se inserta, ni siquiera parece tener preferencia por él, y mucho menos alternar en función de la tecla Ins. Nunca lo había notado antes. Claramente, casi nunca quiero mecanografiar. :-)
TJ Crowder
122
..........
^ <= puntero a "cabezal de impresión"
            /* part1 */
            printf("hello worl");
hola mundo
          ^ <= puntero a "cabezal de impresión"
            /* part2 */
            printf("\b");
hola mundo
         ^ <= puntero a "cabezal de impresión"
            /* part3 */
            printf("\b");
hola mundo
        ^ <= puntero a "cabezal de impresión"
            /* part4 */
            printf("d\n");
hola wodl

^ <= puntero a "cabezal de impresión" en la siguiente línea
pmg
fuente
Si el cursor después de la parte 4 está en la letra 'l', ¿no debería reemplazarse por la letra '\ n'? (resultando en "hola, trabajo")
lucas_turci
@lucas_turci: lo que pasa es que '\n'no tiene representación en pantalla. Lo que ya está ahí permanece igual; no reemplazado por un espacio o cualquier otra representación de carácter.
pmg
44

Si quieres un retroceso destructivo, necesitarás algo como

"\b \b"

es decir, un retroceso, un espacio y otro retroceso.

Peter K.
fuente
Esto todavía deja el carácter del espacio ¿no?
Pacerier
Bueno, sí, pero lo siguiente \bsignificará que el siguiente carácter de salida lo sobrescribirá.
Peter K.
1
¿Qué pasa si no hay un personaje posterior?
Pacerier
Entonces no importa, ¿verdad?
Peter K.
1
Hmm. A menos que su dispositivo implemente una opción de "eliminar el último carácter" (por ejemplo, DEL / 0x7f), estoy perplejo.
Peter K.
8

No es demasiado difícil de explicar ... Esto es como escribir hello worl, presionar la tecla de flecha izquierda dos veces, escribir dy presionar la tecla de flecha hacia abajo.

Al menos, así es como infiero que su terminal está interpretando los códigos \by \n.

Redirija la salida a un archivo y apuesto a que obtendrá algo completamente diferente. Aunque puede que tenga que mirar los bytes del archivo para ver la diferencia.

[editar]

Para elaborar un poco, esto printfemite una secuencia de bytes:, hello worl^H^Hd^Jdonde ^Hes el carácter ASCII # 8 y ^Jes el carácter ASCII # 10. Lo que ve en su pantalla depende de cómo su terminal interprete esos códigos de control.

Nemo
fuente
1

Use un solo retroceso después de cada carácter printf("hello wor\bl\bd\n");

Dorotea
fuente
"hola wod \ n"? Qué significa eso?
Elias Hasle