Zeile einrücken bei der Ausgabe auf der Konsole



  • Hallo Zusammen!
    Ich arbeite mit Visual Studio 2017 und programmiere in C++. Zurzeit habe ich ein Problem bei der Ausgabe auf der Konsole und ich komme da nicht weiter.
    Eigentlich wollte ich eine Zeilennummer, das Datum, ein Zahlencode und einen langen String immer in einer Zeile ausgeben. Das passt aber nicht immer, weil der String teilweise zu lang für die Konsole ist (siehe Beispiel, Zeile 2).

    Hier mal ein Beispiel:
    1 2017-09-12 1234 "irgendein langer Text"
    2 2017-09-12 2345 "nooooooooooooccch
    ein längerer Text"
    3 2017-09-12 3456 "irgendein langer Text"

    jetzt würde ich es gerne so lösen:
    1 2017-09-12 1234 "irgendein langer Text"
    2 2017-09-12 2345 "nooooooooooooccch
    ..............................-> ein längerer Text"
    3 2017-09-12 3456 "irgendein langer Text"

    Also das bei einem automatischen Zeilenumbruch der Text immer eingerückt wird. Meine Idee ist, das ich die Ausgabe vielleicht in einer Art Tabelle mache. Ich weiß aber nicht wie man das lösen kann, hat jemand von euch eine Idee? Oder eine andere Idee wie ich die Ausgabe übersichtlicher gestalten kann?
    (Ich hoffe ihr verseht was ich meine)

    Vielen Dank schon mal an alle!



  • @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    Oder eine andere Idee wie ich die Ausgabe übersichtlicher gestalten kann?

    Die Konsole breiter ziehen.

    Ich würde im Jahr 2018 nicht meine Lebenszeit mit Formatierungen auf der Textkonsole verschwenden.

    Verwende entweder eine GUI zur Ausgabe oder schreibe ein einfaches HTML-File.



  • @manni66
    Breiter kann man die Konsole nicht ziehen, die geht schon über das ganze Fenster.
    Ich mache ein Praktikum und da wurde mir gesagt, ich soll die Formatierung ändern....



  • @manni66 sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    Verwende entweder eine GUI zur Ausgabe oder schreibe ein einfaches HTML-File.

    Wie genau löst man das denn mit einem HTML-File? 🙂



  • @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    Wie genau löst man das denn mit einem HTML-File? 🙂

    @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    Meine Idee ist, das ich die Ausgabe vielleicht in einer Art Tabelle mache

    Genau das, eben mit HTML-Tags.



  • @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    Ich mache ein Praktikum und da wurde mir gesagt, ich soll die Formatierung ändern....

    Dann frag doch mal nach, was du genau machen sollst.



  • @manni66
    ok danke für deine Antwort! Ich setzte mich jetzt dran und probiere ein wenig aus! 🙂



  • Du musst herausfinden,
    wie breit deine Konsole ist (Anzahl Zeichen),
    wie viele Zeichen deine ZEilen/Zeitangabe hat,
    wie lang der Text ist, den du ausgeben sollst.

    Etwas rechnen und dann die Ausgabefunktion entsprechend benutzen.

    Nimmst du cout oder printf?



  • @dirkb
    Meine Konsole ist 237 Zeichen breit und für die Datumangabe brauche ich bis zu 34 Zeichen.
    Der Text den ich ausgeben soll, ist immer unterschiedlich lang. Mal passt er auch in die Zeile und mal nicht.
    Für die Ausgabe verwende ich cout .



  • Ich hab hier noch ein Schnipsel was ich mir mal gespeichert habe (habs nicht selbst geschrieben). Das könnte dir zumindest bei Windows helfen:

    #include <Windows.h>
    
    
    void SetWindow(int Width, int Height) {
    
    	_COORD coord;
    	coord.X = Width;
    	coord.Y = Height;
    
    	_SMALL_RECT Rect;
    	Rect.Top = 0;
    	Rect.Left = 0;
    	Rect.Bottom = Height - 1;
    	Rect.Right = Width - 1;
    
    	HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);      // Get Handle
    	SetConsoleScreenBufferSize(Handle, coord);            // Set Buffer Size
    	SetConsoleWindowInfo(Handle, TRUE, &Rect);            // Set Window Size
    }
    
    
    
    int main() {
    
    	SetWindow(128, 64);
    	return 0;
    }
    


  • @zhavok
    Ich bin mir nicht ganz sicher, wie ich diesen Code benutzen soll...Ich glaub ich hab nicht ganz verstanden wie er funktioniert. Kannst du mir da vielleicht eine kleine Hilfestellung geben?



  • @honeybee
    Du kopierst dir einfach die SetWindow Funktion mit in deinen Code. In deiner main-Funktion rufst du sie dann auf. Du kannst darüber das Fenster der Konsole vergrößern. Das ganze funktioniert über die Windows API. Nun hast du mehr Platz für deinen Text. Das war doch dein Anliegen oder?



  • @zhavok
    Ne nicht ganz. Das Fenster meiner Konsole hat ja schon die maximal Größe und geht über den ganzen Bildschirm. Aber mein Text, den ich ausgebe, ist immer noch zu lang und wird deswegen automatisch abgeschnitten und der Rest wird in der nächsten Zeile ausgegeben. Diese Zeile würde ich gerne einrücken, sodass sie in der selben Höhe anfängt wie der Text in der Zeile davor.



  • Du musst die Länge Deiner Ausgabe für Zeilennummer, Datum und Zahlencode berechnen (addieren).
    Dann ermittelst Du die Gesamtlänge Deiner Zeile: Obige Länge + Länge Deines Strings.
    Wenn diese Gesamtlänge Zeilenlänge überschreitet, gibst Du entsprechend weniger Zeichen von Deinem String aus (substr).
    In der nächsten Zeile gibst Du dann entsprechend der Länge von Zeilennummer, Datum und Zahlencode (siehe erster Satz) Leerzeichen oder '-' oder was auch immer aus.
    Danach dann den Rest Deines Strings (substr).



  • Vielleicht die Zeichen einzeln ausgeben, mitzählen und machst dann einen Zeilenumbruch.
    Die maximale Zeilen- und Spaltenanzahl bekommst Du mit

    GetLargestConsoleWindowSize( hndl ).X;
    GetLargestConsoleWindowSize( hndl ).Y;
    //hndl ist das obige HANDLE
    

    Es gibt auch die Möglichkeit für die aktuelle Zeilen- und Spaltenanzahl, aber ich meine auch, Du solltest das lieber in eine Datei schreiben. Auch eine Text-Datei oder so.



  • @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    Meine Konsole ist 237 Zeichen breit und für die Datumangabe brauche ich bis zu 34 Zeichen.

    Es gibt Modifier für cout, mit denen du eine Mindestlänge oder auch eine Maximallänge festlegen kannst.

    Da gibst du das Datum mit Mindestlänge (35) aus und dann den Text mit Maximallänge (202).
    Ist der Text länger als 202 Zeichen, dann gibst ein Leerzeichen mit Mindestlänge aus und dann maximal 202 Zeichen ab Stelle 202.
    Ist der Resttext länger als 202 Zeichen, dann ab Stelle 404, usw



  • Log-Meldungen auf ne fixe Konsolenbreite zu formatieren finde ich komisch.
    Was ich mal gemacht habe, wo ich sehr glücklich damit war, war mehrzeilige Log-Meldungen (also welche die wirklich Zeilenumbrüche enthalten) so zu formatieren wie hier im Kopfposting beschrieben. Das verbessert IMO sehr die Übersichtlichkeit von Logfiles - hilft beim Überfliegen. Allerdings auch nur wenn man in dem Text-Editor/-Viewer den man verwendet das automatischen Umbrechen von langen Zeilen ausgeschaltet hat.

    Ich würde dir in diesem Fall also empfehlen den Rat von @manni66 zu befolgen:

    Dann frag doch mal nach, was du genau machen sollst.



  • @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    @manni66
    Breiter kann man die Konsole nicht ziehen, die geht schon über das ganze Fenster.

    In dem Fall, sag doch einfach Deinem Betreuer er solle sich einen größeren Bildschirm kaufen:D

    Spaß beiseite, ich würde keine Zeilennummern reinschreiben, weil das jeder ansatzweise taugliche Texteditor anzeigt bzw. anzeigen kann.

    Vielleicht noch eckige Klammern um das Zeug wie Datum etc. und dann finde ich hebt sich der Text in der nächsten Zeile auch besser ab.

    [2017-09-12 1234] "irgendein langer Text"
    [2017-09-12 2345] "nooooooooooooccch
    ein längerer Text"
    [2017-09-12 3456] "irgendein langer Text"

    Wenn das nicht gefällt, wäre die nächste Lösung Notepad++ runterladen und eine User-Defined language anlegen, die das Logfile highlighted. Ist super einfach, habs zum ersten Mal gemacht und geht in 2 Minuten. Ist nicht weniger windows-abhängig als in der Konsole rumfrickeln.

    Wenn das immer noch nicht passt (dann wird aber die Konsolenausgabe auch nicht passen) kann man darüber nachdenken eine HTML Tabelle zu generieren.

    LG



  • Danke für alle eure Antworten! Ich habe es jetzt erstmal so gelöst, wie ich es bei @Belli und @DirkB verstanden habe. Vermutlich werde ich es aber irgendwann nochmal ändern weil das Format ja jetzt abhängig von der Fenstergröße ist.
    Hier meine Lösung (Ich habe versucht es zum Verständnis etwas zu kürzen):

     void testV1::ausgebenderDatei()
    {
    string aktDatum;
    int aktFehlercode;
    string aktText;
    int textSize;
    
    //Schleife zum Durchlaufen von my_file(Array wo meine Daten gespeichert sind)
    for (int i=0; i<1000; i++)
    {
    //Laufvariable linksbündig ausgeben
    cout << setiosflags(ios::left) << setw(4) << i << "  " << resetiosflags(ios::left);
    
    //Methoden um Daten aus der i-ten-stelle von my_file zu bekommen
    aktDatum = getDatum();
    aktFehlercode = getFehlercode();
    aktText = getText();
    
    textSize = aktText.size();
    
    //Ausgabe von Datum & Fehlercode
    cout << Datum << "  ";
    cout.file('0'); //Leerstellen mit 0 füllen
    cout.file(' ');
    
    //bei Ueberschreiten der Zeilenlänge(203 Stellen)
       if(textSize > 203)
         { 
          int AnzahlvonZeilenText = TextSize /202 +1;
          for (int y = 0, y< AnzahlvonZeilenText; y++)
          {
           // String auftrennen sooft wie die Anzahl an benötigten Zeilen in string mit 202 Zeichen
            string s;
            s = aktText.substr(y * 202, 202);
            cout << s;
            
           //bei einem string der kleiner ist als 202 zeichen sind keine Leerzeichen notwendig
            if (s.size() <202)
            {
              break;
            }
           //Leerzeichen um Text einzuruecken
           for (int l = 0; l< 35 ; l++)
           {
             cout << "  ";
           }
          }
    cout << endl;
    }
    //Ausgabe bei kleinen Textzeilen
    else
    {
    cout << aktText << endl;
    }
    }
    }
    


  • @honeybee sagte in Zeile einrücken bei der Ausgabe auf der Konsole:

    //Leerzeichen um Text einzuruecken

    Da reicht ein Leerzeichen mit einer Mindestbreite von 35 (bzw) die aktuelle Länge) Zeichen aus.

    Und die maximale Textlänge (202) gehört zumindest in eine (globale) Konstante.
    (besser wäre die aktuelle Konsolenbreite)

    Und spiel mal mit den Grenzbereichen (201, 202 und 203 lange Zeilen) rum, ob das passt.