Verwenden Sie einen Stream-Manipulator (endl) oder ein Newline-Escape-Zeichen (\ n)?

12

Ich habe keinen spezifischen Kontext, in dem ich die Frage stelle, aber als ich ein Einsteigerbuch über C ++ las, bemerkte ich, dass sowohl ein Endl-Stream-Manipulator als auch ein Newline-Escape-Zeichen beim Umgang mit einem Stream-Objekt verwendet wurden.

Das Beispiel lautet wie folgt:

cout << "Hello World" << endl;
cout << "Hello World\n";

Meine Fragen sind:

  1. Ist es angemessener, den Stream-Manipulator (endl) in einer bestimmten Situation und ein Escape-Zeichen in einer anderen Situation zu verwenden?
  2. Gibt es in Bezug auf die Effizienz Nachteile bei der Verwendung einer der beiden Methoden?
  3. Sind sie vollständig austauschbar?
  4. Ich habe gelesen, dass eine Escape-Sequenz als einzelnes Zeichen gespeichert ist. Bedeutet das, dass es sinnvoller ist, endl zu verwenden, wenn Sie nur wenig Speicher benötigen?
  5. Verbraucht der Stream-Manipulator in irgendeiner Weise Speicher, wenn ja, mehr als die Escape-Sequenz?

Danke, StackExchange Entschuldigung, wenn ich dies im falschen Abschnitt gepostet habe, dachte ich, dass es als Datenstruktur gezählt wird.

Nathan Taylor
quelle
2
endl bewirkt auch einen Flush bei einigen Streams, '\ n' nicht.
James

Antworten:

12

o << std::endl entspricht dem folgenden Code:

o.put(o.widen('\n'));
o.flush();

Mit anderen Worten, sollten Sie nur verwenden, std::endlwenn Sie den Stream leeren müssen. Beispielsweise:

  • Sie führen einen zeitaufwändigen Vorgang durch und möchten sicherstellen, dass Sie zuvor eine Meldung anzeigen.
  • Ein anderer Prozess wartet auf Ihre Ausgabe.
  • Wenn mehr als ein Thread oder Prozess ausgeführt wird, müssen Sie möglicherweise die Ausgabe leeren, damit die Ausgabe von jedem Thread oder Prozess korrekt angezeigt wird. (Andernfalls können scheinbar zufällige Ausgabeblöcke in unangenehmen Abständen verschachtelt werden.)

Wenn Sie nicht brauchen , um den Strom zu spülen, dann verwenden Sie \nstatt std::endl. Die zusätzlichen Anrufe flushkönnen die Leistung beeinträchtigen (manchmal erheblich).

Weitere Informationen finden Sie unter cppreference.com .

In Bezug auf der Speichernutzung: Sorgen über \nVergleich mit std::endlziemlicher Sicherheit ist eine unnötige Mikro-Optimierung, aber im Allgemeinen, würde ich erwarten , dass \nweniger Speicher zu nehmen. \nist nur noch ein Byte am Ende eines String-Literales, während das Schreiben std::endlvom Compiler in (wahrscheinlich inline) Funktionsaufrufe von putund übersetzt wird flush.

Plattformspezifische Unterschiede bei den Zeilenenden (Windows \r\ngegenüber Linux und OS X \n) werden auf einer niedrigeren Ebene behandelt als std::endlund \n:

  • Wenn ein Stream im Textmodus geöffnet wird, wird er beim Schreiben \nautomatisch in das entsprechende plattformspezifische Zeilenende übersetzt. Wenn Sie ein plattformspezifisches Zeilenende lesen, wird es vom Stream automatisch in übersetzt \n.
  • Wenn ein Stream im Binärmodus geöffnet wird, werden alle Zeilenenden wörtlich durchlaufen, und es liegt an Ihnen.
  • Für std::coutund std::cininsbesondere sind sie behandelt , als ob sie Textmodus.
Josh Kelley
quelle
1

1) Verwenden Sie für die Portabilität endl. Windows Newlines sind \r\nLinux \nund Mac \r. Bearbeiten: Gemäß Kommentaren werden leitungssystemspezifische Endungen auf einer niedrigeren Ebene behandelt.

2) endlspült den Stream, "\n"nicht.

3) Abhängig von der Portabilität.

Sie können die Speichernutzung minimieren, indem Sie so oft wie möglich auf einen anderen Speicher zugreifen endl. Dies verringert jedoch die Leistung.

Bearbeiten: Beseitigen Sie einige Fehler.

Kent
quelle
2
Mac ist seit OS X Unix-basiert und damit auch \nauf jedem modernen Rechner lauffähig.
7
Entschuldigung, aber das ist falsch. endlund \nin Bezug auf plattformspezifische Leitungsenden gleichwertig sind; Plattformunterschiede werden auf einer niedrigeren Ebene behandelt.
Josh Kelley
2
Dein erster Punkt ist falsch. endl () sendet '\ n' an den Stream (zusätzlich zum Leeren). Das Zeichen '\ n' wird in das plattformspezifische Zeichen konvertiert End of line sequence(vorausgesetzt, der Textmodus ist aktiviert). Das End of line sequenceist konvertiert zurück zu ‚\ n ' , wenn sie aus einer Datei lesen. Punkt 3) ist zweifelhaft. Und der letzte Absatz ist wieder falsch: Durch das Leeren sparen Sie keinen Platz, und durch das Leeren mehr als erforderlich wird Ihr Code verlangsamt (der Zweck des Puffers besteht darin, die Schreibeffizienz auf einem langsamen Gerät zu verbessern).
Martin York