「バックスペース」エスケープ文字「\ b」:予期しない動作?


101

だから私はようやくK&Rを読んでいて、最初の数ページの中で、バックスペースエスケープ文字があることを学びました\b

だから私はそれをテストしてみると、いくつかの非常に奇妙な動作があります:

#include <stdio.h>

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

出力は

hello wodl

誰かこれを説明できますか?

回答:


145

結果は、使用しているターミナルまたはコンソールプログラムの種類によって異なりますが、ほとんどの\b場合、非破壊的なバックスペースです。カーソルを後方に移動しますが、そこにあるものは消去しません。

したがって、hello worlパーツのコード出力は

こんにちは世界
          ^

...(どこに^カーソルがあるかを示します)次に、(端末上で)消去せずに\bカーソルを2つ後ろに移動する2つの文字を出力します。

こんにちは世界
        ^

カーソルがにあることに注意してくださいr。次に、が出力されd、が上書きされて、次のようにrなります。

こんにちは
         ^

最後に、\n非破壊的な改行であるを出力します(これも、ほとんどの端末で、明らかにあなたのものを含みます)。そのため、lは変更されず、カーソルは次の行の先頭に移動します。


1
消去されない場合、なぜ「r」がなくなったのですか?
セソイド

1
@cesoid:
TJ Crowder 2016年

それはあなたの例が出力に適合しないというだけの理由で、考えられる説明の例ではありません。
セソイド

5
@cesoid rはに置き換えられdます。説明はまだ当てはまります。
syockit 2016年

1
@cesoid:端末について興味深い。Windowsでは、cmd.exeおよびcommand.comターミナルは常に挿入するわけではありません(Insキーを使用して動作を切り替えることができます)。私のメインの* nixコンピューターのGnomeターミナルは常に挿入され、Insキーに基づくトグルがはるかに少ないことを優先するようにも見えないことに驚きました。以前はそれに気づかなかった。明らかに私はタイプオーバーをほとんど望んでいません。:-)
TJクラウダー

122
..........
^ <=「印字ヘッド」へのポインタ
            /* part1 */
            printf("hello worl");
こんにちは世界
          ^ <=「印字ヘッド」へのポインタ
            /* part2 */
            printf("\b");
こんにちは世界
         ^ <=「印字ヘッド」へのポインタ
            /* part3 */
            printf("\b");
こんにちは世界
        ^ <=「印字ヘッド」へのポインタ
            /* part4 */
            printf("d\n");
こんにちは

^ <=次の行の「印字ヘッド」へのポインタ

パート4の後のカーソルが「l」の文字にある場合、「\ n」に置き換えてはいけませんか?(「hello wor」になる)
lucas_turci

@lucas_turci:問題は、'\n'画面に表示がないことです。すでにあるものは同じままです。スペースやその他の文字表現で置き換えられません。
pmg 2016

44

破壊的なバックスペースが必要な場合は、次のようなものが必要になります

"\b \b"

つまり、バックスペース、スペース、および別のバックスペース。


これはまだスペース文字を残していませんか?
パチェリエ

ええ、そうですが、その後\bは次の出力文字で上書きされます。
Peter K.

1
後続のキャラクターがない場合はどうなりますか?
パセリエ

それは問題ではありませんか?
Peter K.

1
うーん。デバイスが「最後の文字を削除する」オプション(たとえば、DEL / 0x7f)を実装していない限り、私は困惑しています。
Peter K.

8

説明するのはそれほど難しくありません...これは、を入力しhello worl、左矢印キーを2回押し、入力しd、下矢印キーを押すのと同じです。

少なくとも、それが私があなたの端末が\b\nコードを干渉していると私が推測する方法です。

出力をファイルにリダイレクトすると、完全に別のものが得られます。ただし、違いを確認するためにファイルのバイトを確認する必要がある場合があります。

[編集]

少し詳しく説明すると、これprintfは一連のバイトを出力します。hello worl^H^Hd^Jは、^HASCII文字#8と^JASCII文字#10です。画面に表示される内容は、端末がこれらの制御コードをどのように解釈するかによって異なります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.