Tabellen in c++
-
Ein Array kommt dieser Sache schon sehr nahe, allerdings besitzen die verschiedenen Spalten auch verschiedene Datentypen.
Da liegt also das Problem. Ein einfaches zweidimensionales Array bringt dich hier nicht weit.
Die Anzahl spalten ist unveränderlich, die anzahl Zeilen jedoch dynamisch.
Am Besten nimmst du, wenn die Anzahl der Spalten von vornherein bekannt ist, einfach separate Arrays für die Spalten (und damit Datentypen).
Damit vermeidest du komplizierte Sachen wie "templatizing" der Datentypen (ein besserer Name für diese Technik fällt mir nicht ein; kennt ihr einen?), Variants (
boost::variant
, falls der Zufall es dir erlaubt,QVariant
aus Qt, u. weitere), Type Erasure (boost::any ) & co., zwischen denen du bei einem einzigen, zweidimensionalen Array entscheiden müsstest.
Ich bin noch lange kein Profi-Programmierer, aber so würde ich argumentieren :xmas1:
-
Dies ist ja im wesentlichen dasselbe, was belli zuvor schon geschrieben hat.
Dann habe ich einfach für jede Spalte einen Array, anstatt für jede Zeile einen Struct. Den einzigen Vorteil, den ich daraus sehe ist, dass die Anzahl spalten
fix ist und auch nicht unübersichtlich gross (max ca.12).
Aber das Problem mit der Abspeicherung ist ja deswegen noch nicht gelöst.Wie funktioniert denn dies beispielsweise bei exel?
Ich bin doch nicht der erste, der vor diesem Problem steht.
-
Sag doch konkret, welche Datentypen du für Elemente benötigst. Reicht ein
std::string
nicht?
-
Dann habe ich einfach für jede Spalte einen Array, anstatt für jede Zeile einen Struct. Den einzigen Vorteil, den ich daraus sehe ist, dass die Anzahl spalten
fix ist und auch nicht unübersichtlich gross (max ca.12).Du brauchst überhaupt keine eigene Datenstruktur zu definieren. Je nachdem was du brauchst reicht ein String (
std::string
, kein Zeiger!) oder ein Skalar (int
,float
, ...) als Feldelement.Aber das Problem mit der Abspeicherung ist ja deswegen noch nicht gelöst.
Welches Problem gibt es denn mit einem ganz gewöhnlichen STL-Container (oder allgemein: sequentiellem Array) beim Zugriff auf die Werte
-
sulky schrieb:
Welches Problem löse ich damit?
Das Problem der Datenverwaltung. Du brauchst dann in Deinem struct keinen Zeiger mehr auf die nächste Zeile zu verwalten und der Zugriff auf einzelne Elemente gestaltet sich einfach:
struct zeile { int eins; string zwei; double drei; //usw. }; ... vector<zeile> myVector(5); myVector[0].eins = 4; myVector[1].drei = 2.56; ...
-
typedef struct cell { enum { NUMBER, STRING } type; union { double number; char *string; } data; } cell;
Diese Lösung ist besser als die von Belli. Erstens wird weniger Speicherplatz benötigt und zweitens ist nur EIN Wert möglich, nicht
zwei="2"
unddrei=3.0
gleichzeitig.
-
Hmm, jetzt hab ich mich verraten. Echte Excel-Programmierer verwenden UN.
-
In meinem Beispiel repräsentiert die struct eine ganze Zeile bestehend aus drei Spalten mit verschiedenen Datentypen.
-
excel hacker schrieb:
Diese Lösung ist besser als die von Belli.
Du kannst schon mal keinen
std::string
verwenden, musst dir also mit manueller Speicherverwaltung und den C-String-Funktionen alles zusammenfrickeln. Tolle Lösung.
-
Diese Lösung ist besser als die von Belli.
Deine Lösung ist auf gut Deutsch Blödsinn. Ich habe bereits Variants erwähnt, und die sind hier schon unpassend.
Nexus schrieb:
excel hacker schrieb:
Diese Lösung ist besser als die von Belli.
Du kannst schon mal keinen
std::string
verwenden, musst dir also mit manueller Speicherverwaltung und den C-String-Funktionen alles zusammenfrickeln. Tolle Lösung.Dein Punkt lässt sich ja noch mit hässlichem drumherum lösen (user-provided ctor+dtor). Aber es gibt schlimmere Macken.
Der Benutzer ist auch noch selbst für die Typsicherheit verantwortlich (+ welchen Wert
type
hat) - nervig. Es gibt zudem keine Form von Fehlersignalisierung, wenn mantype
ignoriert und auf einen uninitialisierten Member zugreift ....
-
Könntest du irgendwie aufzeigen wie genau die tabelle aussehen soll?
Sind die Datentypen für die einzelnen Spalten fest? Oder können diese auch "dynamisch" sein.
Wenn die datentypen für die einzelnen spalten fest sind, dann ist dein Ansatz mit der Struct doch korrekt.
Um Zeilen dynamisch zu verhalten kannst du einen Container wie std::vector verwenden:Z.b.
#include <vector> #include <iostream> struct table_line { std::string column1; float column2; int column3; }; void print_line(table_line &line) { std::cout<<line.column1<<", "<<line.column2<<", "<<line.column3<<"\n"; } int main() { std::vector<table_line> table; table_line line; line.column1 = "hallo"; line.column2 = 12.5f; line.column3 = 100; table.push_back(line); print_line(table[0]); table[0].column3 = 200; print_line(table[0]); return 0; }
Ausgabe:
hallo, 12.5, 100
hallo, 12.5, 200Im Grunde der Vorschlag, den auch Belli gebracht hat.
Und wegen speichern und laden der Tabelle.
Hierfür könntest du eine csv Datei erstellen.
Für das einlesen könnte dir dieser Thread helfen: Dateiinhalt - Komma-Separator - Wie elegant auslesen?