[fstream] Nach einem Read bis zum Ende kann nicht geschrieben werden. (aus: File durchsuchen)
-
*strike* so funktionierts einwandfrei
int length_int; Stream_prvt.seekg (0, ios::end); // Länge des Files ausfiondig machen length_int = Stream_prvt.tellg(); Stream_prvt.seekg (0, ios::beg); char *File_ch = new char[length_int]; // Speicher in der Grösse des Files allozieren memset(File_ch, '*', strlen(File_ch) - 1); // mit memset wird der ganze reservierte Speicher auf einen bestimmten Wert gesetzt Stream_prvt.read(File_ch,length_int); // get ganzes File delete File_ch; File_ch=NULL; // reservierter Filespeicher löschen
[edit] funktioniert doch noch nicht so richtig, richtig
also das einlesen in die Variable schon aber, wenn ich noch
Stream_prvt << "#" << Section.c_str() << "\n";// Section schreiben
nach der read-Funktion habe, wird nichts ins File geschrieben und wenn ich die ganze Lese-Sache auskommentiere funktioniert das schreiben ohne Probleme[/edit]
-
roN schrieb:
*strike* so funktionierts einwandfrei
Kaum.
roN schrieb:
char *File_ch = new char[length_int]; // Speicher in der Grösse des Files allozieren
Während du hier 1 byte zu wenig reservierst (nullbyte für das Ende des Strings)
roN schrieb:
memset(File_ch, '*', strlen(File_ch) - 1); // mit memset wird der ganze // reservierte Speicher auf einen // bestimmten Wert gesetzt
Initialisierst du hier irgend ne Zufällige Länge (was ist wenn im allozierten speicher bereits an Stelle 3 ein 0 steht? oder vielleicht an 1. Stelle?
roN schrieb:
Stream_prvt.read(File_ch,length_int); // get ganzes File
Den schönen Nullabschluss überschreibst du hier dann ungeschickterweise wieder (hättest du ein Byte mehr alloziert und dieses auch null gesetzt und anschliessend length_int bytes gelesen, hättest du den für den String nötigen Nullabschluss.)
roN schrieb:
delete File_ch; File_ch=NULL; // reservierter Filespeicher löschen
Hier wiederum verursachst du ein klassisches Memoryleak... was mit new [] alloziert wird, muss mit delete [] freigegeben werden. Delete selber gibt nur das Element an der entpsrechenden Adresse frei.
-junix
-
Zum Schreib-Problem: Prüfe mal kurz vorher auf bad() eventuell hat der Stream ein Problem damit, dass er eigentlich am Dateiende ist. In diesem Fall müsstest du nochmals einen seek auf das Ende machen.
-junix
-
Okay, ich hab's jetzt so verbessert, aber schreiben kann ich immer noch nichts, am schluss kommt die Meldung "Stream_prvt ist nicht good()!!!, was kann ich dagegen tun?"
Code:int length_int; Stream_prvt.seekg (0, ios::end); // Länge des Files ausfindig machen length_int = Stream_prvt.tellg(); Stream_prvt.seekg (0, ios::beg); char *File_ch = new char[length_int+1]; // Speicher in der Grösse des Files allozieren _wmemset(File_ch, 0, strlen(File_ch) - 1); // mit memset wird der ganze reservierte Speicher auf einen bestimmten Wert gesetzt if (Stream_prvt.bad()) Application->MessageBox("Stream_prvt ist bad()!!!", "tuut",16); else { Stream_prvt.read(File_ch,length_int); // ganzes File in File_ch speichern if (Stream_prvt.good()) Stream_prvt << "#" << Section.c_str() << "\n";// Section schreiben else Application->MessageBox("Stream_prvt ist nicht good()!!!", "tuut",16); delete [] File_ch; File_ch=NULL; // reservierter Filespeicher löschen } }
-
roN schrieb:
_wmemset(File_ch, 0, strlen(File_ch) - 1);
Äh was soll daran verbessert sein? Wieso nicht memset? Wieso immernoch strlen?
Ahja, ich hasse selbstzitate aber:
junix schrieb:
Zum Schreib-Problem: Prüfe mal kurz vorher auf bad() eventuell hat der Stream ein Problem damit, dass er eigentlich am Dateiende ist. In diesem Fall müsstest du nochmals einen seek auf das Ende machen.
-junix
-
junix schrieb:
In diesem Fall müsstest du nochmals einen seek auf das Ende machen.
Okay, folgendes bringt aber immernoch selbes Resultat:
{ int length_int; Stream_prvt.seekg (0, ios::end); // Länge des Files ausfindig machen length_int = Stream_prvt.tellg(); Stream_prvt.seekg (0, ios::beg); char *File_ch = new char[length_int+1]; // Speicher in der Grösse des Files allozieren memset(File_ch, 0, length_int+1); // mit memset wird der ganze reservierte Speicher auf einen bestimmten Wert gesetzt Stream_prvt.read(File_ch,length_int); // ganzes File in File_ch speichern Stream_prvt.seekg (0, ios::end); if (Stream_prvt.bad()) Application->MessageBox("Stream_prvt ist bad()!!!", "tuut",16); else { if (Stream_prvt.eof()) ShowMessage("End of File ist das Problem"); if (Stream_prvt.good()) Stream_prvt << "#" << Section.c_str() << "\n";// Section schreiben else Application->MessageBox("Stream_prvt ist nicht good()!!!", "tuut",16); delete [] File_ch; File_ch=NULL; // reservierter Filespeicher löschen } }
-
Ahja, fstream::clear müsstest du vermutlich auch noch aufrufen... aber eigentlich würde diese Thematik hier eh besser in den thread den ich nach C++ verschoben habe passen.
Ich teil das hier mindestens mal.-junix
[edit]Ah, verflixt nu hab ich auch wieder gepennt... du musst natürlich den put-zeiger ans Ende schieben (seekp) und nicht den get Zeiger (seekg)[/edit]
-
jaaaaaaaaaaaaaaaa, so funktionierts perfekt! *juhui*
Vielen
Danbk junix!!!!!!!!! :))))))))
noch den Code:{ int length_int; Stream_prvt.seekg (0, ios::end); // Länge des Files ausfindig machen length_int = Stream_prvt.tellg(); Stream_prvt.seekg (0, ios::beg); char *File_ch = new char[length_int+1]; // Speicher in der Grösse des Files allozieren memset(File_ch, 0, length_int+1); // mit memset wird der ganze reservierte Speicher auf einen bestimmten Wert gesetzt Stream_prvt.read(File_ch,length_int); // ganzes File in File_ch speichern Stream_prvt.seekp (0, ios::end); Stream_prvt.clear(); if (Stream_prvt.bad()) Application->MessageBox("Stream_prvt ist bad()!!!", "tuut",16); else { if (Stream_prvt.eof()) ShowMessage("End of File ist das Problem"); if (Stream_prvt.good()) Stream_prvt << "#" << Section.c_str() << "\n";// Section schreiben else Application->MessageBox("Stream_prvt ist nicht good()!!!", "tuut",16); delete [] File_ch; File_ch=NULL; // reservierter Filespeicher löschen } }
-
Nu kannste glaubich auch das Clear wieder rausnehmen... soviel ich weiss impliziert seekX() ein clear...
-junix
-
soviel ich weiss impliziert seekX() ein clear...
Ich glaube da irrst du dich. Wenn ich mich richtig erinnere, ist die Wirkung eines seekX nur für stream.fail() != true definiert.
Ich habe zur Zeit aber leider keinen Standard zur Hand, kann also auch falsch liegen.
<edit>Nach Josuttis' "The C++ Standard Library" muss man, falls das failbit gesetzt ist, clear aufrufen, bevor man wieder mit seekX rumhantieren kann</edit>
-
Ok, kann sein. Mein fehler... bin mir da nichtmehr ganz sicher, hab lange mit dem Schrott geübt und war froh es läuft (wenn auch Langsam...) (o;
-junix