endl vs \n



  • Der entsprechende Ausgabestream.



  • Er meint: Das, was z.B. bei std::cout reingeschoben wurde weird definitiv sichtbar.

    [es sei denn cout wurde umgeleitet... 🙂 ]



  • std::endl sollte den plattformspezifischen zeilenumbruch plus line feed liefern. \n ist nur ein umbruch und kann besonders in filestreams zu schlechter darstellung auf verschiedenen system führen.



  • endl macht genau dies (wie GPC bereits richtig sagte):

    27.6.2.7 - Standard basic_ostream manipulators [lib.ostream.manip] schrieb:

    -1- Effects: Calls os.put(os.widen('\n') ), then os.flush().

    [Footnote: The effect of executing cout << endl is to insert a newline character in the output sequence controlled by cout, then synchronize it with any external file with which it might be associated. --- end foonote]

    Es passiert genau das was dort steht, '\n' ausgeben und flushen (habs eben auch nochmal in der Implementierung von MS und STLPort nachgesehen, nur um sicher zu gehen das dort nicht evtl. doch irgendwelche ifdefs drin sind).

    Greetz



  • Hinter den Streams liegen Streambuffer, die die Ausgabe puffern können, so daß nicht jedes Zeichen einzeln zum eigentlichen Ausgabekanal geschickt werden muß, sondern erst, wenn der Puffer voll ist. Das kann die Geschwindigkeit beträchtlich erhöhen. Manchmal ist es aber erwünscht, daß die Ausgabe auf dem Ausgabegerät geschrieben wird, auch wenn der Puffer nicht voll ist. Dafür gibt es die Methode flush, die von std::endl auch aufgerufen wird.

    Beispiel unter Linux:

    #include <iostream>
    #include <unistd.h>
    
    int main()
    {
      std::ios::sync_with_stdio(false); // schaltet die pufferung für std::cout ein
      std::cout << "Hallo" << '\n';
      sleep(2);
    }
    

    Das Programm gibt den Text "Hallo" erst nach 2 Sekunden aus. Ersetzt man das '\n' durch std::endl erfolgt die Ausgabe sofort und dann erst wird gewartet.

    Tntnet



  • Vielen Dank, hoert sich ja interessant an.

    Ich sollte also besser am Ende einer cout anweisung (wo bei mir meist ein \n folgt) lieber endl waehlen, in der cout Anweisung selbst reichen aber \n voll aus, ja?



  • ich würde endl wählen, wenn "zwingend" sofort abgeschickt werden muss.

    es gibt nicht "das eine oder das andere", sondern zwei unterschiedliche dinge mit unterschiedlichem verhalten.
    :xmas1: (auch mal smily ausprobieren)



  • Hier kommt einfach mal ein Beispiel aus einem Programm von mir:

    std::cerr << "usage: " << progname << " [-h host] [-p port] [-e] {message}\n"
                   "       " << progname << " -l [-h host] [-p port] [-s size] [-c] [-e] [-n]\n"
                   "options:\n"
                   "  -l             receiver-mode\n"
                   "  -h host        hostname (default 127.0.0.1 in sender, 0.0.0.0 in receiver)\n"
                   "  -p port        udp-port to use\n"
                   "  -s size        size of receive-buffer in bytes (default 1024)\n"
                   "  -c             continuous-mode - don't stop after receiving message\n"
                   "  -e             echo message back or receive echo-reply\n"
                   "  -n             don't output newline"
                << std::endl;
    

    Hier erfolgt eine mehrzeilige Ausgabe. Es gibt keinen Grund, den Stream zwischendurch zu leeren. Erst am Ende, wenn die Ausgabe komplett ist, soll das auch sichtbar werden.

    Also einfach als Antwort an Shinja: Genau Richtig 👍

    Tntnet



  • tntnet schrieb:

    Hier kommt einfach mal ein Beispiel aus einem Programm von mir:

    Wobei das Beispiel etwas unpassend gewählt ist - cerr arbeitet ungepuffert (d.h. JEDES Zeichen wird direkt an die Ausgabe weitergeleitet), also brauchst du hier überhaupt kein endl.

    @Shinja: Das kommt auch darauf an, wie dringend du die Ausgabe benötigst. Wenn du am Anfang einer längeren Berechnung ein "Bitte warten!" ausgibst, solltest du es direkt flushen, damit der Nutzer etwas davon hat. Wenn du eine Eingabeaufforderung darstellen willst, brauchst du es nicht (cin und cout sind standardmäßig gekoppelt, dadurch führt jede Eingabe über cin zuerst ein cout.flush() durch).



  • Wakarimashita (ich habe verstanden)

    Danke an alle. Bei cout-cin kombi brauch ich\ endl nicht, vor nem sleep oder ner Berechnung (falls etwas laenger) sollte ich es hingegen besser benutzen. Bei allem andern ist es egal, ob ich am Ende nun endl oder \n einfuege, da sich der Unterschied nicht (oder kaum) bemerkbar macht.

    Vielen Dank



  • Shinja schrieb:

    Bei allem andern ist es egal, ob ich am Ende nun endl oder \n einfuege, da sich der Unterschied nicht (oder kaum) bemerkbar macht.

    Vielen Dank

    Das würde ich so keinesfalls unterschreiben. Wenn ich eine Datei schreibe, ist es ein gewaltiger Unterschied, ob ich byteweise oder blockweise schreibe. Und genau das kann ich mit flush steuern.

    Gerade bei cout/cin ist das in der Regel relativ egal, da diese meistens interaktiv mit dem Anwender kommunizieren, aber wenn ich richtig Massendaten verarbeite, dann ist das schon ein Unterschied.

    Tntnet


Anmelden zum Antworten