Was machen \t und \b?

Lesezeit: 5 Minuten

Benutzeravatar von cimere
Zimer

Ich erwarte diese einfache Codezeile

printf("foo\b\tbar\n");

um “o” durch “\t” zu ersetzen und die folgende Ausgabe zu erzeugen

fo     bar

(vorausgesetzt, dass alle 8 Zeichen ein Tabstopp auftritt). Im Gegenteil, ich bekomme

foo    bar

Es scheint, dass meine Shell \b als “Bewege den Cursor eine Position zurück” und \t als “Bewege den Cursor zum nächsten Tabstopp” interpretiert. Ist dieses Verhalten spezifisch für die Shell, in der ich den Code ausführe? Muss ich auf verschiedenen Systemen unterschiedliches Verhalten erwarten?

  • Für das, was es wert ist, habe ich Ihre “erwarteten” Ergebnisse mit Mingw GCC unter Windows 7 in Powershell erhalten.

    – Japreis

    28. Dezember 2011 um 17:45 Uhr

Benutzeravatar von BRPocock
BRPocock

Nein, das ist mehr oder weniger das, was sie tun sollen.

In C (und vielen anderen Sprachen) können Sie schwer sichtbare/einzugebende Zeichen mit einfügen \ Notation:

  • \a ist Alarm/Glocke
  • \b ist Backspace/Rubout
  • \n ist Zeilenumbruch
  • \r ist Wagenrücklauf (Rücksprung zum linken Rand)
  • \t ist Registerkarte

Sie können auch den Oktalwert eines beliebigen Zeichens mit angeben \0nnnoder der Hexadezimalwert eines beliebigen Zeichens mit \xnn.

  • ZB: der ASCII-Wert von _ ist oktal 137, hex 5f, kann also auch getippt werden \0137 oder \x5fwenn Ihre Tastatur keine hatte _ Schlüssel oder so. Dies ist nützlicher für Steuerzeichen wie NUL (\0) und ESC (\033)

Wie jemand gepostet hat (und dann seine Antwort gelöscht hat, bevor ich ihr +1 geben konnte), gibt es auch einige weniger häufig verwendete:

  • \f ist ein Seitenvorschub/neue Seite (Seite vom Drucker auswerfen)
  • \v ist ein vertikaler Tabulator (eine Zeile nach unten, in derselben Spalte)

Auf Bildschirmen, \f funktioniert normalerweise genauso wie \vaber auf einigen Druckern/Fernschreibern reicht es bis zum nächsten Formular/Blatt Papier.

  • Ich sollte anmerken, dass es eine Tradition (von vielen Terminals unterstützt) gibt, Text zu unterstreichen, genau wie Sie es auf einer Schreibmaschine tun würden, indem Sie Backspaces und _ (Unterstriche) abwechseln und fett schreiben, indem Sie \b eingeben. Dies ist nicht mehr allzu beliebt, aber Sie können es an Orten wie Roff finden. Unter Linux/Unix ist das Programm ul wird diese in ANSI-Escape-Codes übersetzen, die jedoch wahrscheinlich /funktionieren/ werden: printf " • u\b_n\b_d\b_e\b_r\b_l\b_i\b_n\b_e\b_ B\bBO\bOL\bLD\bD \n" | ul

    – BRPocock

    4. Juni 2013 um 21:45 Uhr

Backspace und Tab verschieben beide die Cursorposition. Weder ist wirklich ein “druckbares” Zeichen.

Dein Code sagt:

  1. drucke “foo”
  2. Bewegen Sie den Cursor um eine Stelle zurück
  3. bewegt den Cursor vorwärts zum nächsten Tabstopp
  4. Ausgabe “Balken”.

Um die erwartete Ausgabe zu erhalten, benötigen Sie printf("foo\b \tbar"). Beachten Sie das zusätzliche “Leerzeichen”. Das sagt:

  1. Ausgabe “foo”
  2. Bewegen Sie den Cursor um eine Stelle zurück
  3. gib ein ‘ ‘ aus (das ersetzt das zweite ‘o’).
  4. bewegt den Cursor vorwärts zum nächsten Tabstopp
  5. Ausgabe “Balken”.

Meistens ist es unangemessen, Tabulatoren und die Rücktaste zum Formatieren Ihrer Programmausgabe zu verwenden. Lernen Sie zu verwenden printf() Formatbezeichner. Das Rendern von Registerkarten kann je nach Anzeige der Ausgabe stark variieren.

Dieses kleine Skript zeigt eine Möglichkeit, das Tab-Rendering Ihres Terminals zu ändern. Getestet auf Ubuntu + Gnome-Terminal:

#!/bin/bash
tabs -8 
echo -e "\tnormal tabstop"
for x in `seq 2 10`; do
  tabs $x
  echo -e "\ttabstop=$x"
 done

tabs -8
echo -e "\tnormal tabstop"

Siehe auch man setterm und regtabs.

Und wenn Sie Ihre Ausgabe umleiten oder einfach in eine Datei schreiben, werden Tabulatoren häufig mit weniger als den standardmäßigen 8 Zeichen angezeigt, insbesondere in “programmierenden” Editoren und IDEs.

Also mit anderen Worten:

printf("%-8s%s", "foo", "bar"); /* this will ALWAYS output "foo     bar" */
printf("foo\tbar"); /* who knows how this will be rendered */

IMHO sind Registerkarten im Allgemeinen selten für irgendetwas geeignet. Eine Ausnahme könnte eine Ausgabe für ein Programm generieren, das durch Tabulatoren getrennte Eingabedateien erfordert (ähnlich wie bei kommagetrennten Werten).

Rücktaste '\b' ist eine andere Geschichte … es sollte niemals zum Erstellen einer Textdatei verwendet werden, da es nur dazu führt, dass ein Texteditor Müll ausspuckt. Aber es hat viele Anwendungen beim Schreiben von interaktiven Befehlszeilenprogrammen, die nicht mit Formatzeichenketten allein erreicht werden können. Wenn Sie feststellen, dass Sie es häufig brauchen, schauen Sie sich “ncurses” an, das Ihnen eine viel bessere Kontrolle darüber gibt, wo Ihre Ausgabe auf dem Terminalbildschirm angezeigt wird. Und normalerweise, da es 2011 und nicht 1995 ist, ist eine GUI für hochinteraktive Programme normalerweise einfacher zu handhaben. Aber auch hier gibt es Ausnahmen. Wie das Schreiben eines Telnet-Servers oder einer Konsole für eine neue Skriptsprache.

Benutzeravatar von CB Bailey
CB Bailey

Der C-Standard (eigentlich C99, bin nicht aktuell) sagt:

Alphabetische Escape-Sequenzen, die nicht grafische Zeichen im Ausführungszeichensatz darstellen, sollen Aktionen auf Anzeigegeräten wie folgt erzeugen:

\b (Rücktaste) Verschiebt die aktive Position an die vorherige Position in der aktuellen Zeile. […]

\t (horizontaler Reiter) Verschiebt die aktive Position zur nächsten horizontalen Tabellenposition in der aktuellen Zeile. […]

Beide verschieben nur die aktive Position, keiner soll irgendein Zeichen auf oder über ein anderes Zeichen schreiben. Um mit einem Leerzeichen zu überschreiben, könnten Sie versuchen: puts("foo\b \tbar"); Beachten Sie jedoch, dass bei einigen Anzeigegeräten – beispielsweise einem Daisy-Wheel-Drucker – die o zeigt den transparenten Raum.

Dieses Verhalten ist terminalspezifisch und wird durch den von Ihnen verwendeten Terminalemulator (z xterm) und die Semantik von Terminal, die es bereitstellt. Das Terminalverhalten war in den letzten 20 Jahren sehr stabil, und Sie können sich einigermaßen auf die Semantik von verlassen \b.

\t ist das Tabulatorzeichen und macht genau das, was Sie erwarten, basierend auf der Aktion von \b – Es geht zum nächsten Tabstopp, wird dann dekrementiert und geht dann zum nächsten Tabstopp (was in diesem Fall der gleiche Tabstopp ist, wegen der \b.

  • Ich bin mir nicht sicher, ob ich dir folge, es gibt nur einen \t und so nur eine explizite Bewegung auf einen Tabstopp. \b geht nur eine Position zurück. Im Beispiel \b nicht (notwendigerweise) mit einem Tabstopp beginnen oder enden.

    – CB Bailey

    28. Dezember 2011 um 15:38 Uhr

  • Ich bin mir nicht sicher, ob ich dir folge, es gibt nur einen \t und so nur eine explizite Bewegung auf einen Tabstopp. \b geht nur eine Position zurück. Im Beispiel \b nicht (notwendigerweise) mit einem Tabstopp beginnen oder enden.

    – CB Bailey

    28. Dezember 2011 um 15:38 Uhr

1403580cookie-checkWas machen \t und \b?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy