fstream mit in|out
-
Hallo,
Warum funktioniert dieses Programm (reduziertes Beispiel) nicht richtig?
#include <iostream> #include <fstream> #include <string> int main() { std::string test; std::fstream datei; datei.open("test"); //Auch mit "in|out" kein Erfolg... datei << "test"; //Fehler...: Schreibt nicht, legt nicht an... datei.seekg(0); //"g" oder "p" datei >> test; datei.close(); std::cout << test << std::endl; return 0; }Compiliert tadellos...
Mit "in|out|app" geht es...

Alles unter Debian Lenny mit gcc4.1.3;
Rechte richtig und geprüft!
Danke schonmal!
-
du hast deine flags auf zuerst lesen und dann schreiben gesetzt, wenn du aber zuerst in die datei schreibst solltest du die flags auch zuerst mit schreiben beginnnen...nur so kann ich mir das vorstellen
-
Ich kann dein Problem mit MinGW-GCC-4.2.1 nachvollziehen, kann dir aber nicht sagen warum das so ist. Dass die Reihenfolge von in und out eine Rolle spielt ist imho völliger Humbug, da die Parameter verodert werden und die Reihenfolge dabei keinen Einfluss hat. Ich vermute mal, dass sich der Stream ohne app oder trunc in einer Art undefiniertem Zustand befindet, da unklar ist ob der Zeiger ans Dateiende gesetzt werden soll und damit Text angehängt werden soll oder ob falls die Datei bereits vorhanden ist der Zeiger an den Anfang gesetzt werden soll und die Datei damit überschrieben werden soll. Durch die Angabe von app oder trunc machst du die Sache eindeutig.
#include <iostream> #include <fstream> using namespace std; int main(int argc, char* argv[]) { std::string test; fstream datei("test", ios::out | ios::in | ios::app); // ios::trunc statt ios::app funktioniert ebenfalls //datei.open("test"); das kann man auch direkt im Konstruktor machen datei << "test"; datei.seekg(0); datei >> test; //datei.close() unnötig, erledigt der Destruktor von fstream cout << test << endl; }
-
also ich würde das ganze nicht mit strigns machen sondern mit einzelnen chars
#include <iostream> #include <fstream> using namespace std; int main() { char puffer; fstream datei("test", ios::out | ios::in | ios::app); // ios::trunc statt ios::app funktioniert ebenfalls datei << "test"; datei.seekg(0); char text[5]; int i = 0; while( !datei.eof() ) { datei >> puffer; text[i++] = puffer; } cout << text << endl; }
-
Skym0sh0 schrieb:
also ich würde das ganze nicht mit strigns machen sondern mit einzelnen chars
Schwachsinn. Das hat mit dem Problem, dass die Datei nicht angelegt wird und nichts hinein geschrieben wird, gar nichts zu tun. Außerdem bevorzugt man in C++ immer Strings vor char-Arrays, weil diese einem die Speicherverwaltung abnehmen.
Skym0sh0 schrieb:
char text[5]; int i = 0; while( !datei.eof() ) { datei >> puffer; text[i++] = puffer; }Genauso produziert man fehlerhafte Software. Was ist, wenn die Datei mehr als 5 Buchstaben enthält? Dann hast du einen Buffer Overflow, den du mit der string-Klasse elegant vermieden hättest. Praktisch kannst du damit ja sogar nur 4 Buchstaben einlesen, weil du noch die abschließende '\0' bedenken musst.
Merke: Finger weg von char-Arrays wenn man C++ benutzt.
-
tschuldigung leute
bin auch noch en noob in c++
hab vor c++ java gemacht und da sind die strings ja richtig eifnach und komfortabelund mein erfahrungen mit c++ strings (also der klasse) war auch nicht so pralle
-
OhneName schrieb:
Ich kann dein Problem mit MinGW-GCC-4.2.1 nachvollziehen, kann dir aber nicht sagen warum das so ist. Dass die Reihenfolge von in und out eine Rolle spielt ist imho völliger Humbug, da die Parameter verodert werden und die Reihenfolge dabei keinen Einfluss hat. Ich vermute mal, dass sich der Stream ohne app oder trunc in einer Art undefiniertem Zustand befindet, da unklar ist ob der Zeiger ans Dateiende gesetzt werden soll und damit Text angehängt werden soll oder ob falls die Datei bereits vorhanden ist der Zeiger an den Anfang gesetzt werden soll und die Datei damit überschrieben werden soll. Durch die Angabe von app oder trunc machst du die Sache eindeutig.
Klingt einigermaßen logisch, danke!