Konsolenoutput in Tabellen formatieren [gelöst]



  • @Richard_Wunsch sagte in Konsolenoutput formatieren:

    @Jockelx

    Also muss man doch den Abstand zwischen zwei Wörtern errechnen, um es vernünftig darzustellen!

    Ja, sorry, hatte dich da am Anfang falsch verstanden.



  • @Jockelx

    Habe mich auch nicht gerade deutlich ausgedrückt ^^

    Edit: Ah, außerdem vergleicht man auch nicht zwei Wörter, sondern sucht nur innerhalb des arrays (bzw. vectors) nach dem längsten Wort und setzt das als standard wert für std::setw, richtig?

    Warum vergleichst du noch den zweitgrößten String? Würde das nicht reichen?:

    auto result = std::max_element(v.begin(), v.end(), [](const std::string& s1){
    		return s1.size();
    	});
    
    


  • Falls es noch jemand interessiert: einen bestehenden array kann man mit std::copy in einen fixen array kopieren und mit if (i % 3 == 2) bzw. if (i % 4 == 3) 3 oder 4 Tabellenspalten erzeugen. Siehe Code:

    #include <iostream>
    #include <algorithm>
    #include <array>
    #include <iomanip>
    
    int main()
    {
        std::string test[30] = {"test", "testtestingtest", "testtestingtesttesttestingtest", "testtest", "testing", "testingtest", "testtesting",
                              "test", "test", "test", "testtestingtest", "testtestingtesttesttestingtest", "testtest", "testing", "testingtest",
                              "test", "test", "test", "testtestingtest", "testtestingtesttesttestingtest", "testtest", "testing", "testtestingtest", 
                              "testtestingtesttesttestingtest", "testtest", "testing", "testingtest", "testtesting", "test", "test"};
        
        std::array<std::string, 30> v = {};
        std::copy(std::begin(test),std::end(test),std::begin(v))  ;
        
        auto result = std::max_element(v.begin(), v.end(), [](const std::string& s1, const std::string& s2){
    		return s1.size() < s2.size();
        });
        auto max = result->size() +2;
        for (int i = 0; i<30; i++){
            std::cout << std::setw(2) << i << ' ' << v[i] << std::setw(max-v[i].size()) << ' ';
        if(i % 3 == 2)
           std::cout << '\n';
        }
        return 0;
    }                       
    

    Edit: Den Verweis auf std::copy bitte ignorieren -> siehe unten



  • @Richard_Wunsch

    Aus welchem Grund sollte man das array umkopieren?



  • @manni66

    Falls er bereits vorhanden ist. Oder gibt es die begin() Funktion auch für "einfache" arrays?



  • @Richard_Wunsch sagte in Konsolenoutput in Tabellen formatieren [gelöst]:

    @manni66

    Falls er bereits vorhanden ist. Oder gibt es die begin() Funktion auch für "einfache" arrays?

    Was benutzt du denn in deinem copy?



  • @manni66

    Hahaha danke für den Hinweis. Wie kann man nur solche Tomaten auf den Augen haben?



  • Noch 2 Fragen hierzu - Warum ist es nicht möglich, die Arraylänge mit einem Integer zu beschreiben?

    #include <iostream>
    #include <algorithm>
    #include <array>
    #include <iomanip>
    
    int main()
    {
        int testArrayLength = 30;
        std::string test[testArrayLength  = {"test", "testtestingtest", "testtestingtesttesttestingtest", "testtest", "testing", "testingtest", "testtesting",
                              "test", "test", "test", "testtestingtest", "testtestingtesttesttestingtest", "testtest", "testing", "testingtest",
                              "test", "test", "test", "testtestingtest", "testtestingtesttesttestingtest", "testtest", "testing", "testtestingtest", 
                              "testtestingtesttesttestingtest", "testtest", "testing", "testingtest", "testtesting", "test", "test"};
        
        auto result = std::max_element(std::begin(test), std::end(test), [](const std::string& s1, const std::string& s2){
    		return s1.size() < s2.size();
        });
        auto max = result->size() +2;
        for (int i = 0; i<30; i++){
            std::cout << std::setw(2) << i << ' ' << test[i] << std::setw(max-test[i].size()) << ' ';
        if(i % 3 == 2)
           std::cout << '\n';
        }
        return 0;
    }                       
    
    main.cpp:14:51: error: no matching function for call to ‘begin(std::string [testArrayLength])’
    

    Und warum ist es nicht möglich den Inhalt des Arrays erst im Nachhinein zu definieren?

    #include <iostream>
    #include <algorithm>
    #include <array>
    #include <iomanip>
    
    int main()
    {
        std::string test[] = {};
        test [0] = "test";
        auto result = std::max_element(std::begin(test), std::end(test), [](const std::string& s1, const std::string& s2){
    		return s1.size() < s2.size();
        });
        auto max = result->size() +2;
        for (int i = 0; i<30; i++){
            std::cout << std::setw(2) << i << ' ' << test[i] << std::setw(max-test[i].size()) << ' ';
        if(i % 3 == 2)
           std::cout << '\n';
        }
        return 0;
    }                       
    
    main.cpp:10:51: error: no matching function for call to ‘begin(std::string [0])’
    

    Wenn ich stattdessen std::string test[] = {""}; benutze funktioniert es - warum?



  • @Richard_Wunsch Benutze std::vector!

    Bei Arrays muss die Länge bereits während der Compilezeit feststehen. Bei deinem ersten Beispiel fehlt dir mindestens eine eckige schließende Klammer hinter std::string test[testArrayLength und außerdem muss testArrayLength dafür eine Konstante sein. Also const int testArrayLength = 30; und es wäre möglich.

    Wenn du variabel viele Strings hast oder erst im Programmverlauf die Strings füllen willst, nimm std::vector<std::string>.

    Bei Arrays, die du gleich zuweist wie hier: std::string test[] = {""}; wird die Länge des Arrays automatisch anhand der rechten Seite ermittelt. Dort befindet sich 1 Element. Der Code entspricht also: std::string test[1] = {""};

    Das hier ist Blödsinn: std::string test[] = {};. Was soll das sein - ein Array der Länge 0? Also wirst du in test hier niemals etwas speichern können. Das folgende test [0] = "test"; aus deinem Beispiel geht aber davon aus, dass das Array mindestens die Länge 1 hat. Boom!

    Vergiss fürs erste Arrays und sieh dir vector an!



  • @wob Auch hier vielen Dank für deine Antwort!! In meinem Kopf waren Vektoren immer mehrdimensional, weshalb ich nie darauf zurückgegriffen habe, um nur eine Zahl oder einen String zu speichern.

    Die eckige Klammer war einfach nur schlampig kopiert...

    Mir war nicht bewusst, dass die Arraylänge bereits beim compilen konstant feststehen muss - danke für den Hinweis. Dann macht es natürlich auch Sinn, dass ein einfacher Integer als Beschreibung nicht reicht.