Antworten:
Sie sind verschiedene Charaktere. \r
ist Wagenrücklauf und \n
ist Zeilenvorschub.
\r
Senden Sie auf "alten" Druckern den Druckkopf zurück zum Zeilenanfang und \n
schieben Sie das Papier um eine Zeile vor. Beide waren daher erforderlich, um mit dem Drucken in der nächsten Zeile zu beginnen.
Offensichtlich ist das jetzt etwas irrelevant, obwohl Sie je nach Konsole möglicherweise immer noch in der Lage sind, \r
zum Zeilenanfang zu wechseln und den vorhandenen Text zu überschreiben.
Noch wichtiger ist, dass Unix in der Regel \n
als Trennzeichen verwendet wird. Fenster dazu neigen , zu verwenden \r\n
als eine Linie Separator und Mac (bis O 9) verwendet , verwenden , \r
wie die Linie Separator. (Mac OS X ist Unix-y und wird \n
stattdessen verwendet. Es kann einige Kompatibilitätssituationen geben, in denen\r
stattdessen verwendet wird.)
Weitere Informationen finden Sie im Wikipedia-Artikel .
EDIT: Dies ist sprachempfindlich. In C # und Java bedeutet dies beispielsweise \n
immer Unicode U + 000A, das als Zeilenvorschub definiert ist. In C und C ++ ist das Wasser etwas matschiger, da die Bedeutung plattformspezifisch ist. Siehe Kommentare für Details.
\n
wird garantiert Newline sein (siehe Abschnitt 2.4.4.4). Natürlich wäre es schön, wenn das OP die Plattform spezifiziert hätte ... Außerdem denke ich, dass dieser Detaillierungsgrad für jemanden, der nur nach dem Unterschied fragt, eher verwirrend als nützlich wäre.
In C und C ++ \n
ist es ein Konzept, \r
ein Charakter und \r\n
(fast immer) ein Portabilitätsfehler.
Denken Sie an einen alten Fernschreiber. Der Druckkopf befindet sich in einer Zeile und in einer Spalte. Wenn Sie ein druckbares Zeichen an den Teletyp senden, wird das Zeichen an der aktuellen Position gedruckt und der Kopf in die nächste Spalte verschoben. (Dies ist konzeptionell dasselbe wie eine Schreibmaschine, außer dass Schreibmaschinen das Papier normalerweise in Bezug auf den Druckkopf bewegen.)
Wenn Sie die aktuelle Zeile beenden und mit der nächsten Zeile beginnen wollten, mussten Sie zwei separate Schritte ausführen:
ASCII codiert diese Aktionen als zwei unterschiedliche Steuerzeichen:
\x0D
(CR) bewegt den Druckkopf zurück zum Zeilenanfang. (Unicode codiert dies als U+000D CARRIAGE RETURN
.)\x0A
(LF) bewegt den Druckkopf nach unten in die nächste Zeile. (Unicode codiert dies als U+000A LINE FEED
.)In den Tagen von Teletypen und frühen Technologiedruckern nutzten die Menschen tatsächlich die Tatsache, dass dies zwei getrennte Operationen waren. Wenn Sie eine CR senden, ohne ihr von einem LF zu folgen, können Sie über die bereits gedruckte Zeile drucken. Dies ermöglichte Effekte wie Akzente, Fettdruck und Unterstreichung. Einige Systeme wurden mehrmals überdruckt, um zu verhindern, dass Kennwörter in Papierform angezeigt werden. Bei frühen seriellen CRT-Terminals war CR eine der Möglichkeiten, die Cursorposition zu steuern, um bereits auf dem Bildschirm angezeigten Text zu aktualisieren.
Aber die meiste Zeit wollten Sie eigentlich nur zur nächsten Zeile gehen. Anstatt das Paar von Steuerzeichen zu benötigen, erlaubten einige Systeme nur das eine oder andere. Beispielsweise:
U+0085 NEXT LINE
, aber der tatsächliche EBCDIC-Wert ist 0x15
.Warum haben verschiedene Systeme unterschiedliche Methoden gewählt? Einfach weil es keinen universellen Standard gab. Wo Ihre Tastatur wahrscheinlich "Enter" anzeigt, sagten ältere Tastaturen "Return", was für Carriage Return kurz war. Wenn Sie auf einem seriellen Terminal die Eingabetaste drücken, wird das CR-Zeichen gesendet. Wenn Sie einen Texteditor schreiben, wäre es verlockend, nur dieses Zeichen zu verwenden, wenn es vom Terminal eingeht. Vielleicht haben die älteren Macs deshalb nur CR verwendet.
Jetzt, da wir Standards haben , gibt es mehr Möglichkeiten, Zeilenumbrüche darzustellen. Obwohl Unicode in freier Wildbahn äußerst selten ist, hat es neue Charaktere wie:
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
Noch bevor Unicode auf den Markt kam, wollten Programmierer auf einfache Weise einige der nützlichsten Steuercodes darstellen, ohne sich um den zugrunde liegenden Zeichensatz kümmern zu müssen. C hat mehrere Escape-Sequenzen zur Darstellung von Steuercodes:
\a
(für Alarm), der die Teletyp-Klingel läutet oder das Terminal piepen lässt\f
(für Formularvorschub), der zum Anfang der nächsten Seite wechselt\t
(für Tabulator), der den Druckkopf zur nächsten horizontalen Tabulatorposition bewegt(Diese Liste ist absichtlich unvollständig.)
Diese Zuordnung erfolgt zur Kompilierungszeit - der Compiler sieht \a
und setzt den magischen Wert, der zum Klingeln verwendet wird.
Beachten Sie, dass die meisten dieser Mnemoniken direkte Korrelationen zu ASCII-Steuercodes aufweisen. Zum Beispiel \a
würde zuordnen 0x07 BEL
. Ein Compiler könnte für ein System geschrieben werden, das etwas anderes als ASCII für den Host-Zeichensatz verwendet (z. B. EBCDIC). Die meisten Steuercodes mit bestimmten Mnemoniken konnten Steuercodes in anderen Zeichensätzen zugeordnet werden.
Huzzah! Portabilität!
Naja fast. In C könnte ich schreiben, printf("\aHello, World!");
was klingelt (oder piept) und eine Nachricht ausgibt. Aber wenn ich dann etwas in der nächsten Zeile drucken wollte, musste ich immer noch wissen, was die Host-Plattform benötigt, um zur nächsten Ausgabezeile zu wechseln. CR LF? CR? LF? NL? Etwas anderes? Soviel zur Portabilität.
C hat zwei Modi für E / A: Binär und Text. Im Binärmodus werden alle gesendeten Daten unverändert übertragen. Im Textmodus gibt es jedoch eine Laufzeitübersetzung , die ein Sonderzeichen in das konvertiert, was die Hostplattform für eine neue Zeile benötigt (und umgekehrt).
Großartig, was ist der besondere Charakter?
Nun, das hängt auch von der Implementierung ab, aber es gibt eine implementierungsunabhängige Möglichkeit, dies anzugeben : \n
. Es wird normalerweise als "Zeilenumbruch" bezeichnet.
Dies ist ein subtiler, aber wichtiger Punkt: \n
Wird zur Kompilierungszeit einem implementierungsdefinierten Zeichenwert zugeordnet , der (im Textmodus) zur Laufzeit erneut dem tatsächlichen Zeichen (oder der Zeichenfolge) zugeordnet wird, das von der zugrunde liegenden Plattform zum Verschieben benötigt wird zur nächsten Zeile.
\n
unterscheidet sich von allen anderen Backslash-Literalen, da zwei Zuordnungen beteiligt sind. Diese zweistufige Zuordnung \n
unterscheidet sich erheblich von der geraden Zuordnung \r
, bei der es sich lediglich um eine Zuordnung zur Kompilierungszeit zu CR handelt (oder um den ähnlichsten Steuercode in dem zugrunde liegenden Zeichensatz).
Dies löst viele C- und C ++ - Programmierer aus. Wenn Sie 100 von ihnen abfragen, sagen Ihnen mindestens 99, dass \n
dies Zeilenvorschub bedeutet. Dies ist nicht ganz richtig. Die meisten (vielleicht alle) C- und C ++ - Implementierungen verwenden LF als magischen Zwischenwert für \n
, aber das ist ein Implementierungsdetail. Für einen Compiler ist es möglich, einen anderen Wert zu verwenden. Wenn der Host-Zeichensatz keine Obermenge von ASCII ist (z. B. wenn es sich um EBCDIC handelt), ist er \n
mit ziemlicher Sicherheit kein LF.
Also, in C und C ++:
\r
ist buchstäblich ein Wagenrücklauf.\n
ist ein magischer Wert, der zur Laufzeit (im Textmodus) in die Newline-Semantik der Host-Plattform übersetzt wird.\r\n
ist fast immer ein Portabilitätsfehler. Im Textmodus wird dies in CR übersetzt, gefolgt von der Zeilenumbruchsequenz der Plattform - wahrscheinlich nicht das, was beabsichtigt ist. Im Binärmodus wird dies in CR übersetzt, gefolgt von einem magischen Wert, der möglicherweise nicht LF ist - möglicherweise nicht das, was beabsichtigt ist.\x0A
ist die portabelste Methode, um einen ASCII-LF anzuzeigen, aber Sie möchten dies nur im Binärmodus tun. Die meisten Implementierungen im Textmodus behandeln dies wie folgt \n
.\r\n
ist eigentlich die einzige Möglichkeit, die Zeilen richtig in separate Listenelemente aufzuteilen. Ich frage mich, ob dies ein seltsames HTML-Artefakt ist oder ob es damit zu tun hat, wie Python die Zeichenfolge von meinem request
Objekt aufnimmt .
"\ n" => Newline oder Linefeed (Semantik)
Unix-basierte Systeme verwenden nur ein "\ n", um eine Textzeile zu beenden.
\r
wird verwendet, um auf den Zeilenanfang zu zeigen und kann den Text von dort ersetzen, z
main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}
Erzeugt diese Ausgabe:
hai
\n
ist für neue Linie.
Kurz gesagt, \ r hat den ASCII-Wert 13 (CR) und \ n hat den ASCII-Wert 10 (LF). Mac verwendet CR als Zeilenbegrenzer (zumindest war ich mir bei modernen Macs nicht sicher), * nix verwendet LF und Windows verwendet beide (CRLF).
\ r ist Wagenrücklauf; \ n ist Neue Leitung (Zeilenvorschub) ... hängt vom Betriebssystem ab, was jede bedeutet. In diesem Artikel erfahren Sie mehr über den Unterschied zwischen '\ n' und '\ r \ n' ... in C.
\ r für Wagenrücklauf verwendet. (ASCII-Wert ist 13) \ n wird für neue Zeile verwendet. (ASCII-Wert ist 10)
'\n'
.