[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


Anmelden zum Antworten