Binäre Datei auslesen die zu Beginn jedes Records einen String enthält
-
Hi,
ich versuche mich gerade an einer neuen Übung mit binären Dateien, und versuche die enthaltenen Records der Datei in Objekte einzulesen.
class Team { private: string teamName; int matchesPlayed; int gamesWon; int gamesLost; int pointsWon; int pointsLost; public: Team(string ="",int = 0,int = 0, int = 0, int = 0, int = 0); ~Team(); void setTeamName(string); void setMatchesPlayed(int); void setGamesWon(int); void setGamesLost(int); void setPointsLost(int); void setPointsWon(int); void print(); }; //... Team Konstruktor aus Team.cpp ...// Team::Team(string teamName, int matchesPlayed, int gamesWon, int gamesLost, int pointsWon, int pointsLost) { setTeamName(teamName); setMatchesPlayed(matchesPlayed); setGamesWon(gamesWon); setGamesLost(gamesLost); setPointsWon(pointsWon); setPointsLost(pointsLost); }Das einlesen versuche ich über ein anderes Objekt im Konstruktor:
Table::Table() { Team t1; ifstream inputFile; // open könnte auch hier geschehen inputFile.open("tabletennis.dta", ios::in | ios::binary); if(!inputFile) { cout << "Datei konnte nicht geoeffnet werden!"; exit(1); } inputFile.read(reinterpret_cast<char*> (&t1), sizeof(Team)); t1.print(); }So wie ich es verstanden habe aus Buch und Vorlesungsmaterial sollte es ja möglich sein, als zu speicherndes Ziel ein Objekt anzugeben dass als Attribute die selbe "Signatur" wie der Datensatz hat?
Ich komme hier jedoch scheinbar vor allem mit dem String nicht zurecht.
Mit einen char* habe ich es zwar geschafft den Teamnamen einzulesen, die 5 Integer jedoch nicht. Das, was dann im Objekt steht ist Blödsinn.Das Problem ist, so weit ich es sehe, vor allem der unterschiedlich lange string?
Den hab ich einmal einzeln über getline() herausbekommen, dann hab ich aber immernoch nicht die anderen Werte. Und eigentlich sollte man so einen Record doch irgendwie sinnvoll herausbekommen oder?
-
Stefan_B schrieb:
Table::Table() { ifstream inputFile; // open könnte auch hier geschehen }Schön wenn du es weißt, aber wieso verwendest du es nicht?
-
Gibt es denn einen Grund, außer dass man es gleich im Konstruktor mitgeben kann?
(Außer Code-Reduktion, weniger Befehle in der Abfolge etc.)
-
mit read()/write() verarbeitest du nur den Teil der Daten, die sich innerhalb des Objekts befinden - bei einem std::string sind das einige Zeiger auf extern verwaltete Daten und int-Werte. Wenn du die in eine Datei schreibst und später wieder zurückschreibst, verweisen diese Zeiger auf Müll.
Eine Lösung wäre es, den String gesondert per getline() einzulesen.
-
Stefan_B schrieb:
Code-Reduktion, weniger Befehle in der Abfolge etc.
Reicht dir das nicht

-
Stefan_B schrieb:
Gibt es denn einen Grund, außer dass man es gleich im Konstruktor mitgeben kann?
(Außer Code-Reduktion, weniger Befehle in der Abfolge etc.)
Bist du so geil darauf, eine Zeile mehr zu schreiben oder vermeidest du RAII generell?
-
Da es sich hier nur um Übungen zu bestimmten Themen hält, ist mir das erstmal nicht so wichtig. Reduzieren kann ich, vor allem da ich es weiß, immernoch.
Das Problem aber erstmal abzuarbeiten hat bei Übungen vorrangiges Verhalten anstelle von Code Reduktion. Mein primäres Ziel ist das Verstehen und Lösen des Problems anstatt Shortest-Path-First
Soll bitte aber auch nicht Diskussion sein des Threads hier, Tipps nehme ich trotzdem immer gerne an.Per getline() hatte ich den String bereits schonmal rausbekommen, und dann versucht nur die 5 Integer Werte herauszubekommen aus der File. Hat jedoch leider nicht ganz geklappt.
Dazu hatte ich mir auch ein Array geschrieben dass die 5 Werte entgegen nehmen sollte, ungefähr so:
int helper[5] = {0,0,0,0,0}; inputFile.read(reinterpret_cast<char*> helper, 20);
-
Sperr dich nicht so
Das hindert beim Lernen 
Hier mal einen Hinweis:
http://www.c-plusplus.net/forum/286289MfG f.-th.
-
Den String mit getkine hatte ich ja schon raus, sagte ja schon dass das kalppte. Aber die folgenden Integer hab ich nicht rausbekommen, nur weiß ich nicht wieso.
Der Zeiger müsste ja auf dem ersten Byte des Integers stehen, und wenn ich dann bei read sage, hole mir 20 Byte an die Adresse eines int Arrays mit 20 Byte, das sollte ja klappen.
Im Hex Editor sehe ich alle Imfos korrekt, aber leider schaffe ich es nicht sie so rauszuziehen wie ich es scheinbar verstehe bei der Umsetzung.
-
Ist der String denn inklusive NewLine in der Datei enthalten? Oder hast du ein anderes Trennzeichen, das das Ende des Strings markiert?
getline() liest per Default bis zum NewLine, du kannst aber als dritten Parameter eine Alternative angeben. Alternativ besteht die Möglichkeit, die String-Länge vor den Daten zu speichern und anschließend genau so viele Zeichen in ein char-Array einzulesen und per assign() in den String zu schieben.
-
Ich kann mich irren. Ich denke du versuchst das, wie viele Beispiele im Netz C++ im C-Stil.
Hier mal ein Beispiel C++:
Dateiname siehe Quelltext
Marktplatz|43 Johann|23Quelltext dazu:
#include <iostream> #include <fstream> #include <string> int main() { std::ifstream inf("data.txt"); std::string name; while(!std::getline(inf, name, '|').eof()) //read thru pipe { std::string number; std::getline(inf, number); //read thru newline std::cout << name << " TRENNZEICHEN " << number << std::endl; } }Wenn noch string zu int oder int zu string, siehe stringstream.
Die Trennzeichen kannst du an deine Ideen anpassen. Es muss kein '|'MfG f.-th.
-
Hi,
eine interessante Idee. Als bis jetzt effektivste Methode habe ich es bis jetzt so gelöst:
.. getline(inputFile,name,'\0'); inputFile.read( reinterpret_cast<char*> (&t1), 5 * sizeof(int)); ..wobei ich aber die Read Funktion in Team integriert habe (die Datei selbst aber aus Table heraus öffne und als Referenz übergebe) und somit klappt das dann. Über den String hinweg das zu machen mit read ist wohl definitiv nicht möglich.
-
Du tust dir keinen Gefallen, wenn du immer wieder C++ im C-Stil versuchst.
Versuche das auf halbwegs aktuellem C++ Weg! Viele von uns sind durch unser Programmiervorkenntnisse negativ belastet was den C++ Weg betrifft. Also Ballast abwerfen und C++ im C-stihl möglichst vermeiden. Leider sind die Tutorials und andere Beispiele im Netz voll von nicht optimalem Quelltext.
Rückfälle sind auch bei mir nicht auszuschliessen

Aber ich versuch mich zu bessern.MfG f.-th.
-
Das verstehe ich gerade nicht was du mir genauer sagen möchhtest, eventuell aber auch gerne nähere Ausführung per PN.
Auch ich hab vor 8 Jahren mit C angefangen und 2 Jahre nichts anderes gemacht.. was nicht immer einfach ist beim Lösen von Problemen.