Probleme mit Datei E/A
-
So wie du es beschrieben hast geht es, aber die Lösung gefällt mir irgendwie nicht.
Beim rumprobieren ist mir aufgefallen, dass wenn ich das nicht in einer Klassenfunktion sondern in einer normalen Funktion stehen habe ganz gut funktioniert: Bei Linux und Windoof. Nur eben nicht in der Klasse.
Hat das irgendein Grund?Manuel
-
struct record { string name; int punkte; };Wie groß ist denn sizeof record wenn name = "Hallo" und wenn name = "Hallo Welt" ist ?!?
Wie wärs mit nem op<< und op>> für record ? Da hast Du dann auch alle Informationen wenn Du es denn unbedingt binär speichern willst...
-
sizeof hat bei mir auch Probleme gemacht sobald der Datensatz aus verschiedenen Datentypen zusammengesetzt war. Ich fülle seitdem Strings immer mit Leerzeichen auf Solllänge auf. Datensatzbreite kann dann errechnet werden, da Speicherbedarf der Datentypen bekannt ist. Auch ein direkter Zugriff auf die Datensätze (gehe zu Satz x) ist nur bei konstanter Länge aller Datensätze möglich.
-
Hallo,
es geht nicht darum, ob dir meine Lösung gefällt oder nicht, dein Lösungsansatz ist schlicht weg falsch (read/write funktioniert mit deiner Struktur einfach nicht) und ich hab versucht einen anderen Weg zu zeigen. Ich kann ja verstehen, dass du es auf "deine Art" machen willst, aber wenn der Ansatz falsch ist, wird es recht schwer. Egal wie du es lösen willst, du musst 'name' und 'punkte' einzeln abspeichern, wobei read/write bei 'name' nicht funktioniert.
Beim rumprobieren ist mir aufgefallen, dass wenn ich das nicht in einer Klassenfunktion sondern in einer normalen Funktion stehen habe ganz gut funktioniert: Bei Linux und Windoof. Nur eben nicht in der Klasse.
Hat das irgendein Grund?Wenn der Programmcode sonst gleich ist, dürfte das nicht passieren.
Grüße
Fux
-
Man kann schon read und write dafür benutzen.
operatoren für die stuct überladen und in diesem das binärspeichern übernehmen. Nur ist die Frage ob man das so wirlich machen will ?!
Mein Tip wäre: Schreibe mal einen op<< und op>> für die Struktur. Dann kanste es sehr einfach weiterverarbeiten. Du Arbeitest dann wie Fux sagte mit << . Nur wird dann aus Deiner Struktur ein Datentyp der intern das schreiben übernimmt. Dort würde ich dann ein int speichern das die Länge des Strings angibt (der kann das so lange sein wie er will) und danach die Highscore.
Das solltest Du dann lesen und schreiben können wie Du willst.
Ich persönlich würde den op<< op>> überladen um den String in einer Zeile speichern zu können und mit getline wieder auszulesen. In der nächsten Zeile die Score...
-
@Fux
Ja es war ansonsten so ziemlich der gleiche code, um net zu sagen fast der selbe@Knuddlbar
Überladene Operatoren....
und das als C++ Anfänger ?!
Manuel
-
allesbelegt schrieb:
und das als C++ Anfänger ?!

Manuelread und write als Anfänger ?!
Na, willst nun Anfänger bleiben oder was gegen tun ?

Hier mal ein wenig was zum Spielen.
(Ich weiß nicht genau wie man das Problem mit der Zahl und den String am elegantesten löst....)
#include <iostream> #include <string> // FÜr Beispiele #include <vector> #include <fstream> #include <algorithm> #include <iterator> using namespace std; struct record { string name; int punkte; }; std::ostream & operator<<(std::ostream & out,const record & rec) { out<<rec.punkte<<' '; // Leerzeichen schreiben. Wenn Du sonst 12 Punkte hast und der Name 11Evil ist // Wäre das eingelesene falsch out<<rec.name<<'\n'; return out; } std::istream & operator>>(std::istream & in,record & rec) { in>>rec.punkte; in.get(); // Das Leerzeichen wegwerfen (bzw. das Trennzeichen) getline(in,rec.name); // Und den rest der Zeile für den Namen verwenden return in; } void tryOne() { // Beispielhandling für eigene lese Routinen std::vector<record> recvec; record temp; cin.clear(); temp.name = "Hallo"; temp.punkte = 12; recvec.push_back(temp); temp.name = "Hallo2"; temp.punkte = 13; recvec.push_back(temp); temp.name = "Hallo3"; temp.punkte = 14; recvec.push_back(temp); cout<<recvec[0]; cout<<recvec[1]; cout<<recvec[2]; fstream file("t:\\test.txt",ios::out); file<<recvec[0]; file<<recvec[1]; file<<recvec[2]; file.close(); file.open("t:\\test.txt",ios::in); file>>temp; cout<<temp; file>>temp; cout<<temp; file>>temp; cout<<temp; } void trytwo() { // Details hab ich im letzten Beitrag von // http://c-plusplus.net/forum/viewtopic.php?t=39470 // erklärt std::vector<record> recvec; record temp; cout<<"Eingabesyntax:\n Punkt Text\n Zwischen den Punkten und dem Textein leerzeichen einfügen!\nBeenden mit einem Buchstaben am Anfang\n\n"; while(cin>>temp) { recvec.push_back(temp); } fstream file("T:\\Test.txt",ios::out); copy(recvec.begin(),recvec.end(),ostream_iterator<record>(file,"\n")); file.close(); recvec.clear(); file.open("T:\\Test.txt",ios::in); istream_iterator<record> beg(file); istream_iterator<record> end; copy(beg,end,back_inserter(recvec)); copy(recvec.begin(),recvec.end(),ostream_iterator<record>(cout,"")); } int main(int argc, char * argv[]) { tryOne(); cout<<"Und nun trytwo\n\n"; trytwo(); return 0; }
-
ahmm..
ich glaub ich nehm dann doch die lösung von Fux

Manuel
-
Na, wer sich das nich mal anschaut wird immer davor zurückschrecken.
Das meiste ist nur ein Beispiel wie es verwendet wird.
std::ostream & operator<<(std::ostream & out,const record & rec) { out<<rec.punkte<<' '; // Leerzeichen schreiben. Wenn Du sonst 12 Punkte hast und der Name 11Evil ist // Wäre das eingelesene falsch out<<rec.name<<'\n'; return out; } std::istream & operator>>(std::istream & in,record & rec) { in>>rec.punkte; in.get(); // Das Leerzeichen wegwerfen (bzw. das Trennzeichen) getline(in,rec.name); // Und den rest der Zeile für den Namen verwenden return in; }Das hier ist das Geheimnis um record auch mit << und >> verwenden zu können.
und das als C++ Anfänger ?!

Aber wennst Dir das Beispiel nich anschauen magst...
-
Warum schauen solche sachen bei mir immer erst auf den dritten blick einfach aus?
Oder ist es doch net soo einfach ..Kannst du mir mal die Zeile genauer erklären?
std::ostream & operator<<(std::ostream & out,const record & rec)Funktionieren tuts auf jeden Fall
Manuel