"Backspace" kaçış karakteri "\ b": beklenmeyen davranış?


101

Sonunda K&R ile okuyorum ve ilk birkaç sayfada bir geri boşluk kaçış karakteri olduğunu öğrendim \b.

Bu yüzden test etmeye gidiyorum ve çok garip davranışlar var:

#include <stdio.h>

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

Çıktı

hello wodl

Bunu kimse açıklayabilir mi?

Yanıtlar:


145

Sonucunuz, ne tür bir terminal veya konsol programı üzerinde olduğunuza bağlı olarak değişecektir, ancak evet, çoğu \bdurumda, tahribatsız bir geri silme. İmleci geri hareket ettirir, ancak orada olanı silmez.

Yani hello worlparça için kod çıktıları

merhaba dünya
          ^

... (burada ^imleç olduğunu gösterir) Sonra iki çıkışı \bimleci geriye iki yer hamle karakterleri olmadan (terminal üzerine) silme:

merhaba dünya
        ^

İmlecin şimdi r. Sonra çıktılar d, bu da üzerine yazar rve bize şunu verir:

merhaba wodl
         ^

Son olarak, \ntahribatsız bir satırsonu olan (yine, görünüşe göre sizinki dahil olmak üzere çoğu uçbirimde) çıktılar , böylece ldeğişmeden bırakılır ve imleç bir sonraki satırın başına taşınır.


1
Eğer silinmiyorsa, o zaman neden "r" gitmiş?
cesoid

1
@cesoid: "Sonuçlarınız, ne tür bir terminal veya konsol programında olduğunuza bağlı olarak değişecektir"
TJ Crowder

Sadece örneğiniz çıktıya uymuyor, bu yüzden olası bir açıklamaya örnek değil.
cesoid

5
@cesoid rile değiştirilir d. Açıklama hala uyuyor.
syockit

1
@cesoid: Terminal hakkında ilginç. Windows'ta cmd.exeve command.comterminalleri her zaman eklenmez (davranışı değiştirmek için Ins tuşunu kullanabilirsiniz). Ana * nix bilgisayarımdaki Gnome Terminalinin her zaman eklendiğini, hatta Ins anahtarına bağlı olarak daha az geçiş yapma tercihine sahip olmadığını görünce şaşırdım. Bunu daha önce hiç fark etmemiştim. Açıkçası neredeyse hiç yazı yazmayı istemiyorum. :-)
TJ Crowder

122
..........
^ <= "yazdırma kafasına" işaretçi
            /* part1 */
            printf("hello worl");
merhaba dünya
          ^ <= "yazdırma kafasına" işaretçi
            /* part2 */
            printf("\b");
merhaba dünya
         ^ <= "yazdırma kafasına" işaretçi
            /* part3 */
            printf("\b");
merhaba dünya
        ^ <= "yazdırma kafasına" işaretçi
            /* part4 */
            printf("d\n");
merhaba wodl

^ <= sonraki satırdaki "yazıcı kafasına" işaretçi

4. bölümden sonraki imleç 'l' harfindeyse, '\ n' ile değiştirilmemeli mi? (sonuç "merhaba wor" ile sonuçlanır)
lucas_turci

@lucas_turci: Sorun şu ki '\n'ekranda gösterimi yok. Zaten orada olan aynı kalır; boşluk veya başka herhangi bir karakter temsili ile değiştirilmez.
pmg

44

Yıkıcı bir geri boşluk istiyorsanız, şunun gibi bir şeye ihtiyacınız olacak:

"\b \b"

yani bir geri al, bir boşluk ve başka bir geri al.


Bu hala boşluk karakterini bırakıyor, değil mi?
Pacerier

Evet, ama sonraki \b, bir sonraki çıktı karakterinin üzerine yazacağı anlamına gelecektir.
Peter K.

1
Ya sonraki karakter yoksa ?
Pacerier

O zaman önemli değil, değil mi?
Peter K.

1
Hmm. Cihazınız bir "son karakteri sil" seçeneğini (örneğin DEL / 0x7f) uygulamadıkça, kafam karışıyor.
Peter K.

8

Açıklaması çok zor değil ... Bu, yazmak hello worl, sol ok tuşuna iki kez dbasmak , yazmak ve aşağı ok tuşuna basmak gibidir.

En azından, terminalinizin \bve \nkodlarını bu şekilde yorumladığını anladım .

Çıkışı bir dosyaya yönlendirin ve bahse girerim tamamen başka bir şey elde edersiniz. Yine de farkı görmek için dosyanın baytlarına bakmanız gerekebilir.

[Düzenle]

Biraz detaylandırmak için, bu printfbir bayt dizisi yayar: hello worl^H^Hd^Jburada ^HASCII karakter # 8 ve ^JASCII karakter # 10. Ekranınızda gördükleriniz, terminalinizin bu kontrol kodlarını nasıl yorumladığına bağlıdır.


1

Her karakterden sonra tek bir geri alma tuşu kullanın printf("hello wor\bl\bd\n");


"merhaba wod \ n"? Bu ne anlama geliyor?
Elias Hasle
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.