Frage

Wie sind \r und \n anders? Ich denke, es hat etwas mit Unix vs Windows vs. Mac zu tun, aber ich bin nicht sicher, wie genau sie sind anders, und was für / Spiel in regulären Ausdrücke suchen.

War es hilfreich?

Lösung

Sie sind verschiedene Charaktere. \r ist Wagenrücklauf und \n ist Zeilenvorschub.

Auf „alten“ Drucker gesendet \r den Druckkopf zurück zum Anfang der Zeile, und \n voran das Papier um eine Zeile. Beide waren daher notwendig, den Druck auf der nächsten Zeile zu beginnen.

Ganz offensichtlich ist das etwas irrelevant jetzt, obwohl in Abhängigkeit von der Konsole Sie noch in der Lage sein kann \r zu verwenden, um den Anfang der Zeile und überschreiben Sie den vorhandenen Text zu bewegen.

Noch wichtiger ist, neigt dazu, Unix \n als Zeilentrennzeichen zu verwenden; Windows neigt \r\n als Zeilentrennzeichen und Macs zu verwenden (bis O 9) verwendet \r als Zeilentrennzeichen zu verwenden. (Mac OS X Unix-y, so verwendet \n statt;. Kann es einige Kompatibilitäts Situationen, in denen \r verwendet wird anstelle obwohl)

Weitere Informationen finden Sie in der Wikipedia Newline Artikel .

EDIT: Dies ist sprachempfindlich. In C # und Java zum Beispiel \n immer bedeutet Unicode U + 000A, die als Zeilenvorschub definiert ist. In C und C ++ ist das Wasser etwas trübes, wie die Bedeutung plattformspezifisch ist. Siehe Anmerkungen für Details.

Andere Tipps

In C und C ++, \n ist ein Konzept, \r ein Charakter ist, und \r\n ist (fast immer) eine Portabilität Bug.

Denken Sie an einem alten Fernschreiber. Der Druckkopf ist auf irgendeiner Linie und in einem gewissen Spalte positioniert. Wenn Sie ein druckbare Zeichen an die Fernschreiber senden, druckt er das Zeichen an der aktuellen Position und bewegt den Kopf in der nächsten Spalte. (Dies ist vom Konzept her die gleiche wie eine Schreibmaschine, mit der Ausnahme, dass das Papier Schreibmaschinen typischerweise mit Bezug auf den Druckkopf bewegt.)

Wenn Sie die aktuelle Zeile und beginnen in der nächsten Zeile beenden wollte, musste man zwei getrennte Schritte tun:

  1. den Druckkopf an den Anfang der Zeile bewegen zurück, dann
  2. verschieben Sie es in der nächsten Zeile nach unten.

ASCII codiert diese Aktionen als zwei verschiedene Steuerzeichen:

  • \x0D (CR) bewegt den Druckkopf an den Anfang der Zeile zurück. (Unicode codiert dies als U+000D CARRIAGE RETURN.)
  • \x0A (LF) bewegt den Druckkopf nach unten in der nächsten Zeile. (Unicode codiert dies als U+000A LINE FEED.)

In den Tagen Fernschreiber und frühen Technologie-Drucker, die Menschen tatsächlich nahm sich die Tatsache zunutze, dass diese waren zwei getrennte Vorgänge. Durch eine CR sendet, ohne sie durch ein LF folgenden, können Sie über die Linie drucken Sie bereits gedruckt. Dies erlaubte Effekte wie Akzente, fett und unterstrichen. Einige Systeme überdruckten mehrmals Passwörter zu verhindern, dass in Hardcopy sichtbar ist. Am frühen seriellen CRT-Terminals, war CR eine der Möglichkeiten, um die Cursorposition zu steuern, um Text, der bereits auf dem Bildschirm zu aktualisieren.

Aber die meiste Zeit, Sie wollten eigentlich nur in die nächste Zeile gehen. Anstatt das Paar von Steuerzeichen erfordern, erlaubt einige Systeme nur das eine oder das andere. Zum Beispiel:

  • Unix-Varianten (einschließlich modernen Versionen von Mac) verwendet nur ein LF-Zeichen eine neue Zeile anzuzeigen.
  • Alte (pre-OSX) Macintosh-Dateien nur ein CR-Zeichen verwendet eine neue Zeile anzuzeigen.
  • VMS, CP / M, DOS, Windows und viele Netzwerkprotokolle erwarten nach wie vor beide: CR LF
  • .
  • Old IBM Systeme, die EBCDIC verwendeten auf NL standardisiert - ein Zeichen, das nicht einmal in den ASCII-Zeichen bestehen einstellen. In Unicode sind NL U+0085 NEXT LINE, aber der tatsächliche EBCDIC Wert ist 0x15.

Warum haben verschiedene Systeme wählen verschiedene Methoden? Ganz einfach, weil es kein universeller Standard. Wo die Tastatur wahrscheinlich sagt „Enter“, ältere Tastaturen zu sagen, „Return“ verwendet, die für Carriage Return kurz war. In der Tat, auf einem seriellen Terminal, drückt Return tatsächlich sendet die CR-Zeichen. Wenn Sie einen Text-Editor schreiben würden, wäre es verlockend sein, nur das Zeichen zu verwenden, wie es in vom Terminal kam. Vielleicht ist das, warum die älteren Macs nur CR verwendet wird.

Nachdem wir nun Standards gibt es mehr Wege Zeilenumbrüche darzustellen. Obwohl extrem selten in der freien Natur, hat Unicode neue Charaktere wie:

  • U+2028 LINE SEPARATOR
  • U+2029 PARAGRAPH SEPARATOR

Schon vor Unicode kam, wollte Programmierer einfache Möglichkeiten, ohne sich Gedanken über die zugrunde liegende Zeichensatz einige der nützlichsten Steuercodes darzustellen. C hat mehrere Escape-Sequenzen für Steuercodes darstellen:

  • \a (für Alarm), die die Fernschreiber klingelt oder macht das Terminal Signalton
  • \f (für Formularvorschub), die zu Beginn der nächsten Seite bewegt
  • \t (für Reiter), die den Druckkopf in die nächste horizontale Tab-Position bewegt

(Diese Liste ist absichtlich unvollständig.)

Diese Zuordnung geschieht in Compiler- -. Der Compiler sieht \a und Puts, was Magie-Wert verwendet wird, um die Glocke zu läuten

Beachten Sie that der meisten dieser Mnemotechnik haben direkt Korrelationen zu ASCII-Steuercodes. Zum Beispiel würde \a 0x07 BEL kartieren. Ein Compiler kann für ein System geschrieben werden, die etwas anderes als ASCII für den Host-Zeichensatz verwendet (beispielsweise EBCDIC). Die meisten der Steuercodes, die spezifische Mnemotechnik hatte abgebildet werden könnten Codes in anderen Zeichensätzen zu steuern.

Huzzah! Portabilität!

Nun, fast. In C, konnte ich printf("\aHello, World!"); schreiben, die die Glocke Ringe (oder Töne), und gibt eine Meldung aus. Aber wenn ich will etwas in der nächsten Zeile drucken, dann würde ich noch wissen müssen, was die Host-Plattform auf die nächste Zeile der Ausgabe zu bewegen erfordert. CR LF? CR? LF? NL? Etwas anderes? So viel für die Portabilität.

C verfügt über zwei Modi für I / O: Binär- und Text. Im Binärmodus wird alle Daten, wird übertragen gesendet, wie sie ist. Aber im Textmodus gibt es eine Laufzeit Übersetzung, die ein Sonderzeichen konvertiert, was auch immer die Host-Plattform für eine neue Zeile benötigt (und umgekehrt).

Große, so was ist der besondere Charakter?

Nun, das ist die Umsetzung abhängig, auch, aber es gibt eine implementierungsunabhängige Art und Weise zu spezifizieren: \n. Es ist in der Regel des „Newline-Zeichen“ genannt.

Das ist ein subtiler, aber wichtiger Punkt: \n wird in abgebildet kompilierte Zeit zu einem Implementierung definiert Zeichenwert, der (im Textmodus ) wird dann wieder bei dem abgebildeten Laufzeit auf die tatsächlichen Zeichen (oder eine Folge von Zeichen, die von der zugrunde liegenden Plattform erforderlich) in der nächsten Zeile zu bewegen.

\n ist anders als alle anderen Backslash Literale, weil es zwei Zuordnungen beteiligt. Dieses zweistufige Mapping macht \n wesentlich anders als noch \r, die CR einfach ein Kompilierung-Mapping (oder der ähnlichste Steuercode in welcher der zugrunde liegenden Zeichensatz).

Das stellt viele C und C ++ Programmierer auf. Wenn Sie 100 von ihnen abzufragen sind, mindestens 99 werden Ihnen sagen, dass \n Zeilenvorschub bedeutet. Das ist nicht ganz richtig. Die meisten (vielleicht alle) C und C ++ Implementierungen verwenden LF als magische Zwischenwert für \n, aber das ist eine Implementierung Detail. Es ist denkbar, einen Compiler, einen anderen Wert zu verwenden. In der Tat, wenn der Host-Zeichensatz nicht eine Obermenge von ASCII ist (zum Beispiel, wenn es EBCDIC ist), dann wird \n an Sicherheit grenzender Wahrscheinlichkeit nicht LF sein.

Also, in C und C ++:

  • \r ist buchstäblich ein Wagenrücklauf.
  • \n ist ein magischer Wert, der (im Textmodus) übersetzt wird in Laufzeit zu / von der Newline Semantik der Host-Plattform.
  • \r\n ist fast immer ein Portabilität Bug. Im Textmodus wird diese übersetzt von der Neuzeilensequenz Plattform gefolgt CR - wahrscheinlich nicht, was beabsichtigt ist. Im Binärmodus wird diese übersetzt von einigen magischen Wert, gefolgt CR, dass möglicherweise nicht LF sein - möglicherweise nicht, was beabsichtigt ist
  • .
  • \x0A ist die tragbare Art und Weise einen ASCII-LF, um anzuzeigen, aber Sie wollen nur, dass im Binär-Modus zu tun. Die meisten Textmodus-Implementierungen werden, dass wie \n behandeln.
  • "\ r" => Zurück
  • "\ n" => Newline oder Linefeed (Semantik)

  • Unix-basierte Systeme verwenden nur ein „\ n“, um eine Textzeile zu beenden.

  • DOS verwendet "\ r \ n", um eine Textzeile zu beenden.
  • Einige andere Maschinen verwendet nur „\ r“. (Commodore, Apple II, Mac OS vor OS X, etc ..)

Kurz \ r hat den Wert ASCII 13 (CR) und \ n hat ASCII-Wert 10 (LF). Mac verwendet CR als Zeilentrennzeichen (zumindest, es früher nicht, ich bin nicht sicher, für die moderne macs), * nichts nutzt LF und Windows verwendet sowohl (CRLF).

\r wird verwendet, um den Anfang einer Zeile zu zeigen und den Text von dort ersetzen kann, z.

main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}

erzeugt diese Ausgabe:

hai

\n ist für neue Zeile.

Neben @ Jon Skeet Antwort:

Traditionell \ r \ n, Unix \ Windows verwendet n und Mac \ r, aber neuerer Macs verwenden \ n als sie auf Unix-Basis.

in C # Ich fand sie verwenden \ r \ n in einem String zurück.

\ r Carriage Return; \ N New Line (Line Feed) ... auf dem O, was jede Einrichtung abhängt. Lesen Sie diesen Artikel mehr über den Unterschied zwischen ‚\ n‘ rel="nofollow und '\ r \ n' ... in C.

\ r für Wagenrücklauf verwendet. (ASCII-Wert 13) \ N für neue Linie verwendet. (ASCII-Wert 10)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top