Ký tự thoát “backspace” '\ b': hành vi không mong muốn?


101

Vì vậy, cuối cùng tôi đã đọc qua K&R và tôi đã học được điều gì đó trong vài trang đầu tiên, rằng có một ký tự thoát lùi \b,.

Vì vậy, tôi đi kiểm tra nó, và có một số hành vi rất kỳ lạ:

#include <stdio.h>

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

Đầu ra là

hello wodl

Bất cứ ai có thể giải thích điều này?

Câu trả lời:


145

Kết quả của bạn sẽ khác nhau tùy thuộc vào loại thiết bị đầu cuối hoặc chương trình bảng điều khiển mà bạn đang sử dụng, nhưng có, trên hầu hết \blà một backspace không phá hủy . Nó di chuyển con trỏ về phía sau, nhưng không xóa những gì ở đó.

Vì vậy, đối với hello worlmột phần, mã đầu ra

xin chào lol
          ^

... (nơi ^hiển thị vị trí của con trỏ) Sau đó, nó xuất ra hai \bký tự di chuyển con trỏ về phía sau hai nơi mà không xóa (trên thiết bị đầu cuối của bạn):

xin chào lol
        ^

Lưu ý rằng con trỏ hiện đang ở trên r. Sau đó, nó xuất ra d, ghi đè lên rvà cho chúng ta:

xin chào wodl
         ^

Cuối cùng, nó xuất ra \n, là một dòng mới không phá hủy (một lần nữa, trên hầu hết các thiết bị đầu cuối, bao gồm cả thiết bị đầu cuối dường như của bạn), vì vậy giá trị lnày được giữ nguyên và con trỏ được di chuyển đến đầu dòng tiếp theo.


1
Nếu nó không xóa thì tại sao chữ "r" lại biến mất?
cesoid

1
@cesoid: "Kết quả của bạn sẽ khác nhau tùy thuộc vào loại thiết bị đầu cuối hoặc chương trình bảng điều khiển mà bạn đang sử dụng"
TJ Crowder

Chỉ là ví dụ của bạn không phù hợp với đầu ra, vì vậy nó không phải là ví dụ về một giải thích khả thi.
cesoid

5
@cesoid Cái rđược thay thế bằng d. Lời giải thích vẫn phù hợp.
syockit

1
@cesoid: Thú vị về thiết bị đầu cuối. Trong Windows, không phải lúc nào cũng chèn cmd.execommand.comthiết bị đầu cuối (bạn có thể sử dụng phím Ins để chuyển đổi hành vi). Tôi đã rất ngạc nhiên khi thấy rằng Gnome Terminal trên máy tính * nix chính của tôi luôn luôn chèn, thậm chí dường như không có sở thích nào cho nó ít chuyển đổi dựa trên phím Ins. Chưa bao giờ nhận thấy điều đó trước đây. Rõ ràng là tôi hầu như không bao giờ muốn đánh máy. :-)
TJ Crowder

122
..........
^ <= con trỏ tới "đầu in"
            /* part1 */
            printf("hello worl");
xin chào lol
          ^ <= con trỏ tới "đầu in"
            /* part2 */
            printf("\b");
xin chào lol
         ^ <= con trỏ tới "đầu in"
            /* part3 */
            printf("\b");
xin chào lol
        ^ <= con trỏ tới "đầu in"
            /* part4 */
            printf("d\n");
xin chào wodl

^ <= con trỏ đến "đầu in" trên dòng tiếp theo

Nếu con trỏ sau phần 4 ở ký tự 'l', thì nó có nên được thay thế bằng '\ n' không? (dẫn đến "hello wor")
lucas_turci

@lucas_turci: vấn đề là cái '\n'không có hình đại diện trên màn hình. Những gì đã có vẫn giữ nguyên; không được thay thế bằng dấu cách hoặc bất kỳ biểu diễn ký tự nào khác.
pmg

44

Nếu bạn muốn có một backspace phá hủy, bạn sẽ cần một cái gì đó như

"\b \b"

tức là một backspace, một khoảng trắng và một backspace khác.


Điều này vẫn để lại ký tự khoảng trắng ở đó phải không?
Pacerier

Vâng, có, nhưng sau đó \bsẽ có nghĩa là ký tự đầu ra tiếp theo sẽ ghi đè lên nó.
Peter K.

1
Điều gì sẽ xảy ra nếu không có ký tự tiếp theo?
Pacerier

Sau đó, nó không quan trọng, phải không?
Peter K.

1
Hừ! Trừ khi thiết bị của bạn triển khai tùy chọn "xóa ký tự cuối cùng" (ví dụ: DEL / 0x7f), tôi sẽ bối rối.
Peter K.

8

Không quá khó để giải thích ... Điều này giống như gõ hello worl, nhấn phím mũi tên trái hai lần, nhập dvà nhấn phím mũi tên xuống.

Ít nhất, đó là cách tôi suy luận thiết bị đầu cuối của bạn đang xen vào mã \b\n.

Chuyển hướng đầu ra đến một tệp và tôi cá là bạn sẽ nhận được một thứ hoàn toàn khác. Mặc dù bạn có thể phải nhìn vào các byte của tệp để thấy sự khác biệt.

[biên tập]

Để giải thích một chút, điều này tạo printfra một chuỗi các byte:, hello worl^H^Hd^Jtrong đó ^Hlà ký tự ASCII # 8 và ^Jlà ký tự ASCII # 10. Những gì bạn thấy trên màn hình phụ thuộc vào cách thiết bị đầu cuối diễn giải các mã điều khiển đó.


1

Sử dụng một dấu cách lùi sau mỗi ký tự printf("hello wor\bl\bd\n");


"xin chào wod \ n"? Điều đó nghĩa là gì?
Elias Hasle
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.