Programm will nicht immer speichern



  • Habe ein Problem mit meinem Programm.
    Das soll Termine (weil es ein Terminplaner ist) in eine Datei speichern
    Klappt unter XP auch ganz gut. Unter 98 wird aber nur in seltenen, nicht reproduzierbaren Fälle gespeichert, frei nach dem Motto: "Ne, i moag jetz net"
    Ich bin mit meinem Latein am Ende und hoffe nun, das jemand von euch den Fehler findet, oder mir den alles entscheidenden Hinweis gibt.

    Hier könnt ihr euch die .exe und nen bissel Quelltext laden:
    http://www.diekhof.com/WinTer.rar

    Das is der Ausschnitt aus der Speicherroutine:

    /*
                            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                            ??? WAS LÄUFT HIER SCHIEF ???
    
                            Das sollte passieren:
                            Es werden die Termine so lange in die Datei geschrieben, bis das
                            in der Datei das steht, was drin stehen soll. Maximal wird es aber 99
                            mal Versucht und dann mit einem Fehler abgebrochen.
    
                            Der Inhalt der Datei wird in AnsiString "inhalt" geschrieben und
                            dann als komplettes Paket gesendet, da unter XP das speichern im Netzt
                            unmenschlich lange dauert. Würde ich anstatt in "inhalt" direkt in die
                            Datei schreiben, würde das Speichern von 300 Terminen 2 Minuten dauern.
    
                            Am Ende der While-Schleife wird der Zähler zu Debugzwecken ausgegeben.
    
                            Bei mir passiert nun folgendes:
                            Die Schleife wird nur einmal durchlaufen. Das heißt, die Daten in der
                            Datei stimmen mit denen im Speicher überein. Öffne ich die Datei nun,
                            stehen sie auch wirklich drin. Sobald ich WinTer schließe und neu starte
                            sind die Daten häufig, !!aber nicht immmer!! zurückgesetzt.
    
                            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
                            ES FUNKTIONIERT IN 10%-30% DER FÄLLE AUCH UNTER 98.
                            DIESER FEHLER TRITT UNTER XP NICHT AUF. KONNTE NUR MIT 98/XP TESTEN.
    
                            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
                            */
    
                            zaehler=0;
                            do
                            {
                                    inhalt="";
                                    inhalt2="";
                                    zaehler++;
    
                                    Application->ProcessMessages();
    
                                    ForceDirectories(ExtractFileDir(winterVar->DateiName.c_str()));
                                    inhalt+="[Termine]\nAnzahl="+IntToStr(winterVar->termine.size())+"\n";
                                    inhalt+="Version=2\n";
                                    inhalt+="TimeStamp="+datum+"\n";
                                    for(unsigned int z=0; z<winterVar->termine.size(); z++)
                                    {
                                            Application->ProcessMessages();
    
                                            Termin* t=winterVar->termine.at(z);
                                            inhalt+="["+IntToStr(z)+"]\nTitel="+t->titel.c_str()+"\n";
                                            inhalt+="Klasse="+AnsiString(t->klasse.c_str())+"\n";
                                            inhalt+="Typ="+IntToStr(t->typ)+"\n";
                                            inhalt+="Vorlauf="+IntToStr(t->vorlauf)+"\n";
                                            inhalt+="Periode="+IntToStr(t->periode)+"\n";
                                            inhalt+="VornHinten="+IntToStr(t->vornHinten)+"\n";
                                            inhalt+="Aufbewaren="+BoolToStr(t->keep)+"\n";
                                            inhalt+="Merken="+BoolToStr(t->merken)+"\n";
                                            inhalt+="Ende="+BoolToStr(t->ende)+"\n";
                                            inhalt+="Datum="+t->datum.DateString()+"\n";
                                            inhalt+="Start="+t->erster.DateString()+"\n";
                                            inhalt+="Letzter="+t->endeDatum.DateString()+"\n";
                                    }
                                    ofstream f(winterVar->DateiName.c_str(),ios::trunc);
                                    //Termine schreiben
                                    f << inhalt.c_str();
                                    f.close();
                                    //Termine auslesen
                                    ifstream cf(winterVar->DateiName.c_str());
                                    string temp;
                                    while(cf)
                                    {
                                            getline(cf,temp);
                                            inhalt2+=temp+"\n";
                                    }
                                    cf.close();
                                    check=inhalt2.c_str();
                            //Termine Vergleichen und bei Bedarf neu speichern
                            }while((check!=(inhalt+"\n")) && (zaehler<100));
    
                            if(zaehler>=99) 
                            MessageDlg("Tausend mal probiert,"+
                            "tausend mal is nichts passiert!\n\nDie Termindatei \n"
                            +AnsiString(winterVar->DateiName.c_str())+
                            "\nkonnte nicht gespeichert werden!\n\n"+
                            "Die lokalen Termine stimmten nie mit dem Gespeicherten überein!"
                            ,mtError, TMsgDlgButtons()<< mbOK, 0);
    
                            ShowMessage(zaehler);
    


  • Vielleicht liegt's an der Freigabe von Ordnern? - In Systemordnern kann es z.B. manchmal sein, dass er dich nicht speichern lässt, oder du hast dich mal als Admin und mal als Gast angemeldet... irgend sowas vielleicht?



  • Mir kommt dein exzessiver Gebrauch von c_str() verdächtig vor.
    Versuch doch mal, das nur dort einzusetzen, wo zwingend ein char* erwartet wird. Und dann solltest du zur Sicherheit eine echte Kopie anlegen, siehe FAQ unter "AnsiString".



  • An der Ordnerfreigabe oder am Benutzer liegt es nicht, da es in jedem Ordner zu diesem Problem kommt (auch über Netzwerk). Der Benutzer ist unter 98 (wo es nicht läuft) ja völlig egal, es gibt ja keine "richtigen" Benutzer wie unter XP.

    Mir kommt dein exzessiver Gebrauch von c_str() verdächtig vor.

    Aber warum läuft es dann unter XP problemlos?

    Noch besser is ja, das er scheinbar in die Datei schreibt, diese bei verlassen des Programs aber zurücksetzt. Und das ist eigendlich nicht das Programm, was das zurücksetzten macht, da bei beenden nichts mehr geladen/gespeichert wird.
    Hab mir ne Testdatei mit 300 Terminen erstellt, würde der da zum ende noch mal speichern, würde ich das durch eine kleine "Denkpause" mitgeteilt bekommen.

    Hab mir das mal in den FAQ angesehen. Geht das auch string->AnsiString

    inhalt is nähmlich nen AnsiString.

    Oder mir sagt einer, wie ich Zahlen oder Boolean in string umwandel.
    Dann würde ich string inhalt machen 😉



  • =]xXx[=- schrieb:

    Aber warum läuft es dann unter XP problemlos?

    Wie in der FAQ beschrieben sind bei unsachgemässem Einsatz von c_str die String-Inhalte nicht garantiert. Sie können also falsch sein (oder richtig), müssen es aber nicht.

    Geht das auch string->AnsiString

    Nein das geht nicht. Warum nicht einfach z.B. check = inhalt2; ?



  • Hab den Code jetzt wie folgt umgeschrieben:

    AnsiString inhalt;
    char *check;
    string inhalt2, a;
    do
    {
            zaehler++;
            inhalt="";
            inhalt2="";
    
            Application->ProcessMessages();
    
            ForceDirectories(ExtractFileDir(winterVar->DateiName.c_str()));
            inhalt+="[Termine]\nAnzahl="+IntToStr(winterVar->termine.size())+"\n";
            inhalt+="Version=2\n";
            inhalt+="TimeStamp="+datum+"\n";
            for(unsigned int z=0; z<winterVar->termine.size(); z++)
            {
                    Application->ProcessMessages();
    
                    Termin* t=winterVar->termine.at(z);
                    inhalt+="["+IntToStr(z)+"]\nTitel="+t->titel.c_str()+"\n";
                    inhalt=inhalt+"Klasse="+t->klasse.c_str()+"\n";
                    inhalt+="Typ="+IntToStr(t->typ)+"\n";
                    inhalt+="Vorlauf="+IntToStr(t->vorlauf)+"\n";
                    inhalt+="Periode="+IntToStr(t->periode)+"\n";
                    inhalt+="VornHinten="+IntToStr(t->vornHinten)+"\n";
                    inhalt+="Aufbewaren="+BoolToStr(t->keep)+"\n";
                    inhalt+="Merken="+BoolToStr(t->merken)+"\n";
                    inhalt+="Ende="+BoolToStr(t->ende)+"\n";
                    inhalt+="Datum="+t->datum.DateString()+"\n";
                    inhalt+="Start="+t->erster.DateString()+"\n";
                    inhalt+="Letzter="+t->endeDatum.DateString()+"\n";
            }
            ofstream f(winterVar->DateiName.c_str(),ios::trunc);
            //Termine schreiben
            check = new char[inhalt.Length()+1];
            strcpy(check, inhalt.c_str());
            f << check;
            f.close();
            //Termine auslesen
            ifstream cf(winterVar->DateiName.c_str());
            string temp;
            while(cf)
            {
                    getline(cf,temp);
                    inhalt2+=temp+"\n";
            }
            cf.close();
            inhalt+="\n";
            check = new char[inhalt.Length()+1];
            strcpy(check, inhalt.c_str());
            a=check;
    //Termine Vergleichen und bei Bedarf neu speichern
    }while((a!=inhalt2) && (zaehler<100));
    

    Mit dem Erfolg, das sich kein Erfolg eingestellt hat 😡
    Geht immer noch nicht



  • Kein grund durchzudrehen... Du vergleichst ja auch ein Zeiger mit nem String...

    -junix



  • ich vergleiche "string a" mit "string inhalt2". Meiner meinung nach keine Zeiger.

    Aber das ist auch egal. Er sagt mir das beide gleich sind. Er durchläuft die Schleife nur einmal.

    Hab mir die Speicherbemühungen noch einmal genau angesehen:
    Ich Starte das Prog -> Termin erstellen -> Speichern ->Prog geöffnet lassen
    -> Termindatei ansehen

    Es traten folgende Ereignisse ein
    1. Die Termindatei zeigt keine Veränderung 😞
    2. Die Termindatei ist geändert 🙂

    Ich beende das Prog:
    a) Die Änderungen wurden verworfen 😞
    b) Die Daten wurden gespeichert 🙂

    Wie und wann was eintritt, habe ich noch nicht herausgefunden.
    Wäre aber auch egal, wenn ich nur wüsste, warum das passiert.
    Habe ich etwa eine KI mit eigenem Willen erschaffen 😕



  • Es liegt nicht am speichern und auch nicht am laden.
    Habe ich jetzt alles x-Mal neu gecoded (richtig echt und neu).

    Is jetzt alles auf fstream-Basis. Trotzdem bleibt das Problem.

    Besteht die möglichkeit, das Win die Änderungen der Datei nur temporär macht und es so zu dem Problem kommt??
    Wenn ich die Deitei nach dem Speichervorgang nähmlich im Notpad öffne ist die wahrscheinlichkeit extrem hoch, das die Änderungen erhalten bleiben?

    Ich bin völlig ratlos 😕


Log in to reply