Konsolenoutput in Tabellen formatieren [gelöst]
-
Vielen Dank! Funktioniert hervorragend. Also muss man doch den Abstand zwischen zwei Wörtern errechnen, um es vernünftig darzustellen! Wenn die Tabellen jetzt noch chronologisch kongruent wären, wäre es Perfektion. Aber so geht es auch schon sehr gut.
-
@Richard_Wunsch sagte in Konsolenoutput formatieren:
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.
-
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 mitif (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
-
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 musstestArrayLength
dafür eine Konstante sein. Alsoconst 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 folgendetest [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.