Daten in Dokument(.txt) speichern
-
Hallo,
ich habe eine Klasse Ausruestung mit z.B. einem vector H_Handschuhe mit mehreren Daten (Nummer, Name, Preis).
Diese Daten möchte ich jetzt zeichenweise in einer .txt-Datei abspeichern, doch es wird insgesamt nur ein wirres Zeichen eingespeichert.std::ifstream H_Handschuh;//Aus vorigen Aufgaben (Textkopien) übernommen char ch; std::string zieldateiname; std::cout << "\nBitte Zieldateipfad eingeben: \n"; std::cin >> zieldateiname; for (int i = 0; i <= sizeof(H_Handschuh); i++) { H_Handschuh.get(ch); std::ofstream ziel(zieldateiname.c_str()); ziel.put(ch); }; // ! wird nur ein Zeichen in die Datei eingeschrieben..Dabei denke ich, dass derm ifstream unnötig ist, aber ich weiß auch nicht, wie ich sonst zeichenweise zwischenspeichern kann. Und ohne ifstream fehlt die Klasse zu H_Handschuh.
Mit "Ausruestung H_Handschuh;" stattdessen kann ich nicht mehr zeichenweise zwischenspeichern ("H_Handschuh.get(ch);"). Bin momentan etwas überfragt und kann grade nicht mal mehr einen klaren Gedanken dazu erfassen
Bitte um Hilfe/Tipps.MfG
(Hoffe ist nicht zu wirr, was ich hier geschrieben habe
)EDIT: Grade bemerkt, for-Schleife ist totaler Humbug...
-
xStrykex schrieb:
Hallo,
...(Hoffe ist nicht zu wirr, was ich hier geschrieben habe
)
...Doch, das ist es.

Hier mal eine Idee
class Ausruestung { unsigned Nummer; std::string Name; double Preis; public: Ausruestung(unsigned nummer, std::string name, double preis) : Nummer(nummer), Name(name), Preis(preis) {} friend std::ostream& operator<<(std::ostream& out, const Ausruestung& ausruestung) { out << "Nummer: " << ausruestung.Nummer << " Name: " << ausruestung.Name << " Preis: " << ausruestung.Preis; return out; } };Beispielanwendung
int main(int argc, char const *argv[]) { Ausruestung handschuh(1, "Handschuhe", 100.5); Ausruestung helm(2, "Helm", 80); Ausruestung schwert(3, "Schwert", 10000); std::vector<Ausruestung> vec; vec.push_back(handschuh); vec.push_back(helm); vec.push_back(schwert); std::fstream out("test.txt", std::ios::out); for (std::vector<Ausruestung>::iterator i = vec.begin(); i != vec.end(); ++i) { out << *i << "\n"; } return 0; }
-
xStrykex schrieb:
Diese Daten möchte ich jetzt zeichenweise in einer .txt-Datei abspeichern
was heisst denn bei dir zeichenweise?
meinst du in klarschrift (also ascii), dass ein mensch inder datei auch das lesen kann was du dir im programm denkst?
oder willst zwischen jedem zeiche ein leerzeichen?auf jedenfall sieht die lösung von tobias gerg gut aus. und der vorteil ist dabei auch noch, du kannst es mit std::cout benutzen und nicht nur mit dateien.
zu deinem ifstream, der ist für das einlesen aus dateien da (wie std::cin nur halt auf dateien). das hat nichts (und soll vor allem auch nicht) mit deiner klasse/struktur zu tun.
wenn du also deine erste zeileda wegmachst, soll es semantisch gesehen keinen fehler geben, es sei denn du hast murks geschrieben
-
Ich kann es teilweise nachvollziehen. Mein Problem dabei: Habe noch nicht wirklich mit Referenzen gearbeitet und mit Pointern noch gar überhaupt nicht.
Wenn jemand den obigen Code erklären könnte, was wo passiert an den Stellen mit Referenzen und Pointern wäre ich euch sehr verbunden.
-
pointer und referenzen sind eigentlich ganz einfach, pass auf:
eine pointer variable (erkennbar an dem stern bei der definition) merkt sich im gegensatz zu einer normalen variable nicht den wert, sondern die addresse von einem, naja ich sag mal, wert
int wert = 5; // der wert, und der ist 5 int * pointer = &wert; // ein zeiger auf eine variable, und was die enthält ist eine andere sache. hier enthält sie die 5du sagst also nicht "ok, ich speicher mir die 5 in meiner variable hier" sondern "ich speicher mir die 5 in dem speicher auf den meine variable hier verweist"
in meinem beispiel ist das &wert dafür da, damit der pointer auch die addresse bekommt. & gibt also die speicheraddresse einer variable raus.
auf der anderen seite kannst du hier nicht einfach schreiben "pointer = 5;", denn damit setzt du nur den poiner auf 5, was da heisst, dass er nun auf den speicher mit dem index 5 zeigt. hier musst du auf den verwiesenen speicher zugreifen und das macht man per *.
int wert = 5; // in speicherzelle 0x672bac45 int * pointer= &wert; // verweist auf wert, hat aber selber die Zahl 0x672bac45 intus *pointer = 6; // nun änderst du den wert von der wert Variable auf 6 cout << *pointer << " " << wert; // "6 6" pointer = 7; // hier setzt du die zahl von pointer auf 7 *pointer = 0xDEADBEEF; // hier willst du in den speicher an position 7 schreiben --> wahrscheinlich crashdu kannst mit pointer also mehrere variablen auf den gleichen speicher zeigen und damit denselben (nicht nur dengleichen) wert haben lassen.
referenzen bringen hier ein wenig simplifizierung rein, aber genau das verunsichert viele am anfang:
referenzen sind im prinzip zeiger die nur an ein bestimmte variable gekettet sindint wert = 5; // wie oben eine wert variable int & ref = wert; // diese referenz ist an denselben speicher gekoppelt wie wert ref = 6; // ändert wie beim zeiger den inhalt von wert cout << ref << " " << wert; // "6 6"im umkehrschluss kannst du keine neuzuweisungen machen, sprich die referenz an eine andere variable ketten. genausowenig wie dass du sie an gar keine variable kettest.
in tobias lösung nutzt er referenzen bei dem <<-Operator, denn würde er dies nicht machen, würde der ausgabestrom kopiert. es gäbe also 2 und dass diese beiden nicht gleichzeitig in ein und dieselbe datei schreiben können ist ja sowas von klar. (google mal call by value bzw. call by reference)
-
Ich kommentiere das mal ...
// Die Ausrüstungsklasse hält alles was man für eine Ausrüstung braucht class Ausruestung { unsigned Nummer; // wofür auch immer? std::string Name; // name der Ausrüstung (Helm, Schwert etc.) double Preis; // Der Preis der Ausrüstung (sollte evtl unsigned sein und sich auf Goldmünzen beziehen) public: // Der Konstruktor der Klasse. Nimmt alle Attribute auf die benötigt werden um das Objekt zu erzeugen Ausruestung(unsigned nummer, std::string name, double preis) : Nummer(nummer), Name(name), Preis(preis) {} // Der Ausgabe operator // Wird überschrieben um bequem mit den c++ streams arbeiten zu können. // friend deswegen um auf die Attribute der Klasse zugreifen zu können. // Referenzen um keine Kopien zu erzeugen. // return um Ketten wie im Beispiel gezeigt hinzubekommen. friend std::ostream& operator<<(std::ostream& out, const Ausruestung& ausruestung) { out << "Nummer: " << ausruestung.Nummer << " Name: " << ausruestung.Name << " Preis: " << ausruestung.Preis; return out; } };Beispielanwendung
int main(int argc, char const *argv[]) { // Ausrüstungen anlegen Ausruestung handschuh(1, "Handschuhe", 100.5); Ausruestung helm(2, "Helm", 80); Ausruestung schwert(3, "Schwert", 10000); std::vector<Ausruestung> vec; vec.push_back(handschuh); vec.push_back(helm); vec.push_back(schwert); // Textdatei öffnen std::fstream out("test.txt", std::ios::out); // Über vektor iterieren und daten in datei schreiben for (std::vector<Ausruestung>::iterator i = vec.begin(); i != vec.end(); ++i) { // *i dereferenziert den Iterator out << *i << "\n"; } return 0; }
-
damit ist alles vollständig. noch fragen?

-
Ne soweit ist erstmal alles klar, auch wenn ich die Pointer etwas ... sagen wir mal weniger mag als die Referenzen

Auch schon öfter gelesen, dass Pointer im Gegensatz zu Referenzen eher seltener benutzt werden (sollten).
Aber dauert noch, bis ich alles anwenden kann
Vielen Dank euch beiden

-
naja, beide haben ihren anwendungsfall und ihre gerechtfertigte existenz.
in C und java gibts z.B. keine referenzen (die heissen zwar in java so ähnlich, sind aber im prinzip pointer)referenzen werden hauptsächlich beim aufrufen von funktionen verwendet, call by reference. mit pointer geht das zwar auch, aber da könnte man ja NULL übergeben, das geht mit referenzen nicht
-
xStrykex schrieb:
Ne soweit ist erstmal alles klar, auch wenn ich die Pointer etwas ... sagen wir mal weniger mag als die Referenzen

...Wo siehst du im Beispielcode einen Pointer?

-
Tobias Gerg schrieb:
Wo siehst du im Beispielcode einen Pointer?

Tobias Gerg schrieb:
int main(int argc, char const *argv[])Da dies anscheinend kein pointer ist, bedarf es hier noch einmal einer Erklärung.

EDIT: Wie gesagt, noch nicht mit gearbeitet außer ein klein wenig mit Referenzen (und dort sind bisher nur "&" für Referenzen vorgekommen, meine Annahme: "*" == Pointer)
-
xStrykex schrieb:
...
Tobias Gerg schrieb:
int main(int argc, char const *argv[])Da dies anscheinend kein pointer ist, bedarf es hier noch einmal einer Erklärung.

Dass ist schon ein Pointer, besser gesagt ein Array aus const pointern auf char. Der wird allerdings im Beispielcode nicht verwendet.
xStrykex schrieb:
EDIT: Wie gesagt, noch nicht mit gearbeitet außer ein klein wenig mit Referenzen (und dort sind bisher nur "&" für Referenzen vorgekommen, meine Annahme: "*" == Pointer)
Der * im Code ist um einen Iterator zu dereferenzieren und Iterator != Pointer
Greets
Tobi