“std::endl” vs. “\n”

Lesezeit: 3 Minuten

stdendl vs n
Kopf Geek

Viele C++-Bücher enthalten Beispielcode wie diesen…

std::cout << "Test line" << std::endl;

…das habe ich auch immer gemacht. Aber ich habe stattdessen viel Code von arbeitenden Entwicklern wie diesem gesehen:

std::cout << "Test line\n";

Gibt es einen technischen Grund, einen dem anderen vorzuziehen, oder ist es nur eine Frage des Codierungsstils?

  • Gute Erklärung: cppkid.wordpress.com/2008/08/27/why-i-prefer-n-to-stdendl

    Payton Millhouse

    17. Oktober 2008 um 21:28 Uhr

  • @derobert dieser ist älter als der andere

    – Kira

    13. November 2013 um 15:31 Uhr

  • @HediNaily ist es in der Tat. Aber die Antwort auf der anderen Seite scheint mir etwas besser zu sein, also habe ich mich entschieden, es so zu machen. Auch der andere ist etwas breiter und deckt ebenfalls ab '\n'.

    – Derobert

    13. November 2013 um 15:35 Uhr


  • stackoverflow.com/a/30968225/3163618 kann es zu erheblichen Leistungsunterschieden kommen.

    – qwr

    24. März 2020 um 4:38 Uhr

stdendl vs n
David Thornley

Die unterschiedlichen Zeilenendezeichen spielen keine Rolle, vorausgesetzt, die Datei ist im Textmodus geöffnet, was Sie erhalten, es sei denn, Sie fragen nach Binärdateien. Das kompilierte Programm schreibt das Richtige für das System, für das es kompiliert wurde.

Der einzige Unterschied ist das std::endl löscht den Ausgabepuffer, und '\n' nicht. Wenn Sie nicht möchten, dass der Puffer häufig geleert wird, verwenden Sie '\n'. Wenn Sie dies tun (z. B. wenn Sie die gesamte Ausgabe erhalten möchten und das Programm instabil ist), verwenden Sie std::endl.

  • Oder erwägen Sie die Verwendung ::std::cerr anstatt ::std::cout da es ungepuffert ist und bei jeder Ausgabeoperation gespült wird.

    – Allmächtig

    23. Januar 2010 um 11:45 Uhr

  • @Omnifarious: Kein std::cerr sollte für Fehler reserviert werden. Die beiden Streams werden nicht miteinander synchronisiert. Wenn Sie also Text an cout ausgeben, wird dieser möglicherweise gepuffert, und cerr geht direkt an die Ausgabe, was zu einer Anzeige im gemischten Modus führt. Verwenden Sie cerr für das, wofür es gedacht ist (Fehler) und cout für das, wofür es entwickelt wurde (normale Interaktion).

    – Martin York

    3. Februar 2010 um 16:39 Uhr

  • @Lucas: Nicht mehr als ‘\n’ ist plattformbewusst.

    – CB Bailey

    17. Februar 2010 um 7:39 Uhr

  • @LokiAstari: Das würde ich nicht sagen stderr steht für “Fehler”. Vielmehr ist es für Out-of-Band-Diagnosemeldungen, wenn Sie so wollen. Es sollte möglich sein zu sagen ./prog > file und speichern nur die wahre Programmnutzlast, aber das Programm möchte möglicherweise viel mehr Statusinformationen ausgeben, selbst bei normaler Interaktion.

    – Kerrek SB

    28. November 2011 um 3:01 Uhr

  • “In vielen Implementierungen ist die Standardausgabe zeilengepuffert, und das Schreiben von ‘\n’ verursacht sowieso einen Flush, es sei denn, std::cout.sync_with_stdio(false) wurde ausgeführt.” von hier kopiert

    – GuLearn

    13. August 2013 um 21:01 Uhr

1647276611 642 stdendl vs n
Martin York

Der Unterschied lässt sich wie folgt veranschaulichen:

std::cout << std::endl;

ist äquivalent zu

std::cout << '\n' << std::flush;

Damit,

  • Verwenden std::endl Wenn Sie ein sofortiges Flushen der Ausgabe erzwingen möchten.
  • Verwenden \n wenn Sie sich Sorgen um die Leistung machen (was wahrscheinlich nicht der Fall ist, wenn Sie die << Operator).

ich benutze \n auf den meisten Linien.
Dann benutze std::endl am Ende eines Absatzes (aber das ist nur eine Gewohnheit und normalerweise nicht notwendig).

Entgegen anderer Behauptungen ist die \n Zeichen wird nur dann der richtigen Plattform-Ende-of-Line-Sequenz zugeordnet, wenn der Stream in eine Datei (std::cin und std::cout spezielle, aber immer noch Dateien (oder dateiähnliche) sind).

  • In vielen Fällen ist das „Ausgabe sofort sehen“ ein Ablenkungsmanöver, da cout gebunden ist cinwas bedeutet, dass, wenn Sie Eingaben von lesen cin, cout wird zuerst gespült. Aber wenn Sie einen Fortschrittsbalken oder etwas anzeigen möchten, ohne von zu lesen cindann ist Spülen sicher sinnvoll.

    – Chris Jester-Young

    30. März 2011 um 5:55 Uhr

  • @LokiAstari: Wenn Sie den <<-Operator verwenden, machen Sie sich wahrscheinlich keine Sorgen um die Leistung – warum? Das wusste ich nicht operator<< ist nicht leistungsfähig, oder welche Alternative für die Leistung? Bitte zeigen Sie mir etwas Material, um dies weiter zu verstehen.

    – legends2k

    22. Januar 2014 um 7:33 Uhr


  • @legends2k: Es gibt ein Ammenmärchen, dass C++-Streams nicht so leistungsfähig sind wie C printf(). Obwohl dies bis zu einem gewissen Grad zutrifft, wird der Hauptunterschied in der Geschwindigkeit durch Personen verursacht, die C++-Streams falsch verwenden. stackoverflow.com/a/1042121/14065 Denken Sie in C++ daran, Iostreams mit C-Streams zu entsynchronisieren sync_with_stdio(false) und spülen Sie Ihre Ausgabe nicht kontinuierlich. Lassen Sie die Bibliothek ausarbeiten, wann es zu tun ist. stackoverflow.com/a/1926432/14065

    – Martin York

    22. Januar 2014 um 19:53 Uhr


  • @Loki: Das ist eine urbane Legende sync_with_stdio macht iostreams so schnell wie stdio. Es tut nicht

    – Ben Voigt

    15. September 2015 um 16:30 Uhr

  • @BenVoigt: Ich war vorsichtig mit meiner Formulierung oben (also bin ich zufrieden mit ihnen). Es ist nicht so leistungsfähig wie stdio (weil es mehr kann). ABER Viele der Leistungslücken, über die sich die Leute beschweren, werden durch die Synchronisierung mit stdio verursacht.

    – Martin York

    15. September 2015 um 20:43 Uhr

1647276611 164 stdendl vs n
Martin Beckett

Es kann zu Leistungsproblemen kommen, std::endl erzwingt ein Flush des Ausgabestreams.

  • Und es kann jede andere Verarbeitung durchführen, die das lokale System benötigt, damit dies gut funktioniert.

    – dmckee — Ex-Moderator-Kätzchen

    17. Oktober 2008 um 21:32 Uhr

1647276612 798 stdendl vs n
Emily L.

Ich erinnerte mich, darüber im Standard gelesen zu haben, also hier ist:

Siehe C11-Standard, der definiert, wie sich die Standard-Streams verhalten, da C++-Programme eine Schnittstelle zur CRT bilden, sollte der C11-Standard hier die Flushing-Richtlinie regeln.

ISO/IEC 9899:201x

7.21.3 §7

Beim Programmstart sind drei Textströme vordefiniert und müssen nicht explizit geöffnet werden – Standardeingabe (zum Lesen der konventionellen Eingabe), Standardausgabe (zum Schreiben der konventionellen Ausgabe) und Standardfehler (zum Schreiben der Diagnoseausgabe). Beim anfänglichen Öffnen ist der Standardfehlerstrom nicht vollständig gepuffert; die Standardeingabe- und Standardausgabeströme werden genau dann vollständig gepuffert, wenn festgestellt werden kann, dass sich der Strom nicht auf ein interaktives Gerät bezieht.

7.21.3 §3

Wenn ein Stream ungepuffert ist, sollen Zeichen so schnell wie möglich von der Quelle oder am Ziel erscheinen. Andernfalls können Zeichen akkumuliert und als Block zu oder von der Hostumgebung übertragen werden. Wenn ein Strom vollständig gepuffert ist, sollen Zeichen als ein Block zu oder von der Hostumgebung übertragen werden, wenn ein Puffer gefüllt ist. Wenn ein Strom zeilengepuffert ist, sollen Zeichen als Block an die oder von der Hostumgebung übertragen werden, wenn ein Zeilenumbruchzeichen auftritt. Darüber hinaus sollen Zeichen als Block an die Hostumgebung übertragen werden, wenn ein Puffer gefüllt ist, wenn eine Eingabe in einem ungepufferten Strom angefordert wird oder wenn eine Eingabe in einem zeilengepufferten Strom angefordert wird, der die Übertragung von Zeichen aus der Hostumgebung erfordert . Die Unterstützung dieser Merkmale ist implementierungsdefiniert und kann über die Funktionen setbuf und setvbuf beeinflusst werden.

Dies bedeutet, dass std::cout und std::cin sind vollständig gepuffert dann und nur dann, wenn Sie beziehen sich auf ein nicht interaktives Gerät. Mit anderen Worten, wenn stdout an ein Terminal angeschlossen ist, gibt es keinen Unterschied im Verhalten.

wie auch immer, falls std::cout.sync_with_stdio(false) heißt dann '\n' verursacht selbst bei interaktiven Geräten keine Spülung. Andernfalls '\n' ist äquivalent zu std::endl es sei denn, Sie leiten an Dateien weiter: c++-Referenz auf std::endl.

1647276612 393 stdendl vs n
Nathan

Es ist ein weiterer Funktionsaufruf enthalten, wenn Sie verwenden möchten std::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a) ruft den Operator an << Einmal.
b) ruft den Operator an << zweimal.

  • Es mag offensichtlich sein, aber es hat einen großen Einfluss auf Thread-Programme, bei denen die erste Version im Allgemeinen eine einzelne Zeile in einem Schuss schreibt, während die zweite Version durch Schreibvorgänge von anderen Threads aufgeteilt werden kann. Oft genug schreibe ich std::cout << "hello\n" << std::flush um dies zu vermeiden.

    – funkelt

    22. Juni 2011 um 23:15 Uhr

  • Wie wäre es mit std::cout << "Hello" << "\n";?

    – byxor

    22. Februar 2018 um 20:39 Uhr

  • @byxor Fast dasselbe, mit Ausnahme der Pufferspülung, wie in anderen Antworten beschrieben. Wie auch immer, es ist überflüssig, wenn Sie die beiden Zeichenfolgenliterale zu einem zusammenführen können.

    – iBug

    19. April 2018 um 6:44 Uhr

  • Nun, wenn die auszugebende Zeichenfolge kein Literal ist, dann werden die Aufrufe der << wären in dem Fall 2 ein auch, also würde ich nicht die Notwendigkeit für ein oder zwei behaupten << (oder zwei Funktionsaufrufe im Allgemeinen) ein Unterschied zwischen sein \n und endl.

    – Enliko

    22. November 2018 um 14:30 Uhr


  • Lol nein, das ist nicht der Grund, warum ich \n verwende.

    – Carlo Holz

    27. Februar 2019 um 10:27 Uhr

1647276613 125 stdendl vs n
Ferruccio

Beide schreiben die entsprechenden Zeilenende-Zeichen. Darüber hinaus bewirkt endl, dass der Puffer festgeschrieben wird. Normalerweise möchten Sie endl nicht verwenden, wenn Sie Datei-I/O ausführen, da die unnötigen Commits die Leistung beeinträchtigen können.

  • Es mag offensichtlich sein, aber es hat einen großen Einfluss auf Thread-Programme, bei denen die erste Version im Allgemeinen eine einzelne Zeile in einem Schuss schreibt, während die zweite Version durch Schreibvorgänge von anderen Threads aufgeteilt werden kann. Oft genug schreibe ich std::cout << "hello\n" << std::flush um dies zu vermeiden.

    – funkelt

    22. Juni 2011 um 23:15 Uhr

  • Wie wäre es mit std::cout << "Hello" << "\n";?

    – byxor

    22. Februar 2018 um 20:39 Uhr

  • @byxor Fast dasselbe, mit Ausnahme der Pufferspülung, wie in anderen Antworten beschrieben. Wie auch immer, es ist überflüssig, wenn Sie die beiden Zeichenfolgenliterale zu einem zusammenführen können.

    – iBug

    19. April 2018 um 6:44 Uhr

  • Nun, wenn die auszugebende Zeichenfolge kein Literal ist, dann werden die Aufrufe der << wären in dem Fall 2 ein auch, also würde ich nicht die Notwendigkeit für ein oder zwei behaupten << (oder zwei Funktionsaufrufe im Allgemeinen) ein Unterschied zwischen sein \n und endl.

    – Enliko

    22. November 2018 um 14:30 Uhr


  • Lol nein, das ist nicht der Grund, warum ich \n verwende.

    – Carlo Holz

    27. Februar 2019 um 10:27 Uhr

1647276613 147 stdendl vs n
Özgür

Keine große Sache, aber endl geht nicht in boost::lambda.

(cout<<_1<<endl)(3); //error

(cout<<_1<<"\n")(3); //OK , prints 3

1002430cookie-check“std::endl” vs. “\n”

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

Privacy policy