Karakter pelolosan "backspace" '\ b': perilaku tak terduga?

101

Jadi saya akhirnya membaca K&R , dan saya belajar sesuatu dalam beberapa halaman pertama, bahwa ada karakter melarikan diri backspace \b,.

Jadi saya pergi untuk mengujinya, dan ada beberapa perilaku yang sangat aneh:

#include <stdio.h>

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

Outputnya adalah

hello wodl

Adakah yang bisa menjelaskan ini?

OregonTrail
sumber

Jawaban:

145

Hasil Anda akan bervariasi tergantung pada jenis program terminal atau konsol yang Anda gunakan, tetapi ya, sebagian besar \badalah backspace yang tidak merusak . Ini memindahkan kursor ke belakang, tetapi tidak menghapus apa yang ada di sana.

Jadi untuk hello worlbagian ini, keluaran kode

halo dunia
          ^

... (di mana ^menunjukkan di mana kursor berada) Kemudian ia mengeluarkan dua \bkarakter yang menggerakkan kursor mundur dua tempat tanpa menghapus (di terminal Anda):

halo dunia
        ^

Perhatikan bahwa kursor sekarang berada di r. Kemudian itu keluar d, yang menimpa rdan memberi kita:

halo wodl
         ^

Akhirnya, ia mengeluarkan \n, yang merupakan baris baru non-destruktif (sekali lagi, di sebagian besar terminal, termasuk yang tampaknya milik Anda), sehingga ldibiarkan tidak berubah dan kursor dipindahkan ke awal baris berikutnya.

TJ Crowder
sumber
1
Jika tidak terhapus lalu mengapa "r" hilang?
cesoid
1
@cesoid: "Hasil Anda akan bervariasi tergantung pada jenis program terminal atau konsol yang Anda
TJ Crowder
Hanya saja contoh Anda tidak sesuai dengan keluarannya, jadi ini bukan contoh penjelasan yang mungkin.
cesoid
5
@cesoid The rdiganti dengan d. Penjelasannya masih pas.
syockit
1
@cesoid: Menarik tentang terminal. Di Windows, cmd.exedan command.comterminal tidak selalu masuk (Anda dapat menggunakan tombol Ins untuk mengubah perilaku). Saya terkejut menemukan bahwa Terminal Gnome di komputer utama * nix saya selalu menyisipkan, bahkan tampaknya tidak memiliki preferensi untuk itu apalagi beralih berdasarkan tombol Ins. Tidak pernah menyadarinya sebelumnya. Jelas saya hampir tidak pernah ingin mengetik. :-)
TJ Crowder
122
..........
^ <= penunjuk ke "print head"
            /* part1 */
            printf("hello worl");
halo dunia
          ^ <= penunjuk ke "print head"
            /* part2 */
            printf("\b");
halo dunia
         ^ <= penunjuk ke "print head"
            /* part3 */
            printf("\b");
halo dunia
        ^ <= penunjuk ke "print head"
            /* part4 */
            printf("d\n");
halo wodl

^ <= penunjuk ke "print head" di baris berikutnya
pmg
sumber
Jika kursor setelah bagian 4 berada pada huruf 'l', bukankah seharusnya diganti dengan '\ n'? (menghasilkan "hello wor")
lucas_turci
@lucas_turci: masalahnya adalah bahwa '\n'tidak memiliki representasi di layar. Apa yang sudah ada tetap sama; tidak diganti dengan spasi atau representasi karakter lainnya.
pmg
44

Jika Anda menginginkan backspace yang merusak, Anda memerlukan sesuatu seperti

"\b \b"

yaitu backspace, spasi, dan backspace lainnya.

Peter K.
sumber
Ini masih menyisakan karakter luar angkasa bukan?
Pacerier
Ya, tapi selanjutnya \bberarti karakter keluaran berikutnya akan menimpanya.
Peter K.
1
Bagaimana jika tidak ada karakter berikutnya?
Pacerier
Maka tidak masalah, bukan?
Peter K.
1
Hmm. Kecuali perangkat Anda menerapkan opsi "hapus karakter terakhir" (misalnya DEL / 0x7f), saya bingung.
Peter K.
8

Tidak terlalu sulit untuk dijelaskan ... Ini seperti mengetik hello worl, menekan tombol panah kiri dua kali, mengetik d, dan menekan tombol panah bawah.

Setidaknya, begitulah cara saya menyimpulkan terminal Anda menginterpretasikan kode \bdan \n.

Alihkan output ke file dan saya yakin Anda mendapatkan sesuatu yang sama sekali berbeda. Meskipun Anda mungkin harus melihat byte file untuk melihat perbedaannya.

[edit]

Untuk menguraikan sedikit, ini printfmemancarkan urutan byte:, di hello worl^H^Hd^Jmana ^Hkarakter ASCII # 8 dan ^Jkarakter ASCII # 10. Apa yang Anda lihat di layar Anda bergantung pada bagaimana terminal Anda menafsirkan kode-kode kontrol tersebut.

Nemo
sumber
1

Gunakan satu spasi mundur setelah setiap karakter printf("hello wor\bl\bd\n");

Dorothea
sumber
"halo wod \ n"? Apa artinya?
Elias Hasle