Ausgabe auf Terminal erscheint erst bei Programmende...



  • Hi!
    Würde gern während des Programmablaufs (Terminal Programm ohne grafischer Oberfläche) Ausgaben erzeugen. Das Problem ist, dass meine Ausgaben erst bei Programmende schlagartig erscheinen, anstatt kontinuierlich während des Programmablaufs an den Stellen, an denen sie im Code stehen.

    Als Beispiel mal folgendes kleines Programm, was von 0 bis 9999 zählt und jede Zahl ausgibt. So funktioniert es noch... Die "sinnlosen" Schleifendurchläufe sind lediglich dazu da, das Programm künstlich zu bremsen und rechenarbeit zu simulieren...

    bool printed = 0;
        cout << "i =  ";
        for(int i=0;i<10000;i++){
            for(int j=0;j<100;j++)
                for(int k=0;k<1000;k++){
                    if(!printed){
                        if(i<11)
                            cout << "\b" << i;
                        else if(i<101)
                            cout << "\b\b" << i;
                        else if(i<1001)
                            cout << "\b\b\b" << i;
                        else
                            cout << "\b\b\b\b" << i;
                        printed = 1;
                    }
                }
            printed = 0;
        }
        cout << endl;
    

    Die "\b"s löschen ein Zeichen im Terminal. Ist nur dazu da, um z.B. die 2 an die Stelle zu schreiben, wo zuvor die 1 stand...

    Wenn ich das Programm jetzt aber leicht abändere und die Anzahl der Schleifendurchläufe, die Berechnungen simulieren sollen, erhöhe, erscheint zunächst keine Ausgabe auf dem Bildschirm und wenn das Programm beendet ist, erscheint die finale Ausgabe: 99 (ich habe hier das zählen auf 99 reduziert, damit das Programm nicht zu lange läuft, da ja zwischendurch mehr "Rechen-Schleifen" abgearbeitet werden...).

    Hier der Code:

    bool printed = 0;
        cout << "i =  ";
        for(int i=0;i<100;i++){
            for(int j=0;j<10000;j++)
                for(int k=0;k<1000;k++){
                    if(!printed){
                        if(i<11)
                            cout << "\b" << i;
                        else if(i<101)
                            cout << "\b\b" << i;
                        else if(i<1001)
                            cout << "\b\b\b" << i;
                        else
                            cout << "\b\b\b\b" << i;
                        printed = 1;
                    }
                }
            printed = 0;
        }
        cout << endl;
    

    Erwartet hätte ich stattdessen, dass das Programm langsam von 0 bis 99 zählt...

    Das Problem taucht auch auf, wenn die momentan sinnlosen Zusatzschleifen mit Berechnungen gefüllt sind. Dann würde ich gerne hin und wieder Zwischenstände ausgeben, insbesondere um zu wissen wie weit das Programm bereits ist mit den Berechnungen (diese dauern ne Weile), aber die Ausgaben erscheinen erst bei Programmende, was mir dann wenig nutzt...

    Kann jemand helfen? Gibt es einen Befehl, um die Anzeige sofort zu erzwingen, bevor das Programm weiterläuft?

    Falls es eine Rolle spielt: Ich programmiere unter Linux.



  • Vielleicht wartet das System erst ab bis der Streambuffer genügend Informationen hat bis er ihn ausgibt? Versuch mal irgendwie zu flushen.

    Da das Programm beendet wird, wird auch der buffer geleert.



  • Mit cout << schreibst du ja nur was in den Ausgabebuffer der Konsole. Dieser gibt das aus, sobald er grad zeit hat. Da du dein Programm mit den ganzen Schleifen ständig unter Vollauslastung laufen hast wird der keine Zeit finden den Buffer auszugeben.

    Dazu kannst du das einfach flushen mit

    cout << flush;
    //bzw....
    cout << "Deine Ausgabe\n" << flush;
    

    Das Programm kannst du auch eleganter Bremsen.
    Unter windows gibts da die Sleep(int ms) Funktion (aus der windows.h).
    Sowas gibt es sicherlich auch unter Linux. Wenn nicht in den Standardheadern, dann in irgendeiner Boost Bibliothek. Ich kann mir vorstellen dass das auf jeden Fall in der Boost Thread Library drin ist.

    Hoffe ich konnte dir etwas helfen.
    Hab das mit dem Flush leider nicht ausprobiert, ist aber denke ich das was du gesucht hast.



  • Noch etwas nebenbei

    bool printed = 0;
    

    Sowas ist hässlig, nimm dann lieber

    bool printed = false; //eig. nicht nötig, da die variable automatisch auf false gesetzt wird
    

    Dafür ist bool da.



  • Warum sollte die Variable denn automatisch auf false gesetzt sein? Standardmäßig ist das nicht so.



  • Max3000 schrieb:

    Dazu kannst du das einfach flushen mit

    cout << flush;
    //bzw....
    cout << "Deine Ausgabe\n" << flush;
    

    Jap, das funktioniert!
    Weitere Alternativen, die ich gefunden habe:

    1. nach jedem cout << endl wird automatisch geflusht (und erscheint somit im Terminal)

    cout.flush();
    

    ist das gleiche wie cout << flush - glaube ich.

    Und außerdem kann man die Bufferlänge auf 1 reduzieren (und somit effektiv den Buffer ausschalten):

    cout.setf(ios::unitbuf);
    

    Max3000 schrieb:

    Das Programm kannst du auch eleganter Bremsen.
    Unter windows gibts da die Sleep(int ms) Funktion (aus der windows.h).
    Sowas gibt es sicherlich auch unter Linux. Wenn nicht in den Standardheadern, dann in irgendeiner Boost Bibliothek. Ich kann mir vorstellen dass das auf jeden Fall in der Boost Thread Library drin ist.

    Mein Ziel mit den Schleifen war ja eigentlich nicht, das Programm zu bremsen. In meinem echten Programm gibt es da Berechnungen, die in vielen Schleifen ablaufen, und eine ähnliche Situation wollte ich mit den vielen ansonsten sinnlosen Schleifendurchläufen simulieren, ohne den Beitrag mit einem langen und unübersichtlichen Code zu belasten...

    Max3000 schrieb:

    Hoffe ich konnte dir etwas helfen.
    Hab das mit dem Flush leider nicht ausprobiert, ist aber denke ich das was du gesucht hast.

    Ja, so ist es!

    Danke!



  • FreakY<3Cpp schrieb:

    Noch etwas nebenbei

    bool printed = 0;
    

    Sowas ist hässlig, nimm dann lieber

    bool printed = false; //eig. nicht nötig, da die variable automatisch auf false gesetzt wird
    

    Dafür ist bool da.

    Wo ist der Unterschied zwischen false und 0? Oder auch zwischen true und 1?



  • Es sieht besser aus. 🙂



  • vielleicht noch interessant dass << endl; das gleiche ist wie \n und flush.



  • Braunstein schrieb:

    Warum sollte die Variable denn automatisch auf false gesetzt sein? Standardmäßig ist das nicht so.

    Nicht? Dann tut mir diese Behauptung Leid. Ich bin es so von C# gewohnt :p



  • schreiner schrieb:

    Max3000 schrieb:

    Dazu kannst du das einfach flushen mit

    cout << flush;
    //bzw....
    cout << "Deine Ausgabe\n" << flush;
    

    Jap, das funktioniert!
    Weitere Alternativen, die ich gefunden habe:

    1. nach jedem cout << endl wird automatisch geflusht (und erscheint somit im Terminal)

    Interessant. Jetzt weiß ich auch warum <<'\n' schneller ist als <<endl ^^. Da gabs einen Unterschied und jetzt weiß ich auch welchen.


Log in to reply