string speichern



  • ok danke, ich bin jetzt schonmal um einiges weitergekommen

    in einer schleife ist jetzt folgendes drinnen:

    ofstream datei1, datei2;
    			remove(Zieldateiname1.c_str());
    			remove(Zieldateiname2.c_str());
    			datei1.open(Zieldateiname1.c_str(), ios::binary|ios::out), 
    			datei2.open(Zieldateiname2.c_str(), ios::binary|ios::out);
    			if(!datei2 && !datei1) {
    				system("CLS");
    				system("COLOR 0C");
    				cerr << "Error: Saving attempt failed! (17243)\n\n\n\a\a\a";
    				system("PAUSE");
    				exit(-1);
    			}
    			string enter2 = ((Nenner + ";") + Schritt);
    			datei1.write(reinterpret_cast<const char*>(&HauptZahl), sizeof(datei1));
    			datei2.write(reinterpret_cast<const char*>(&enter2), sizeof(datei2));
    

    es sollen also die dateien alle X mal neu gespeichert werden...
    es funktioniert aber nur ohne schleife, mit schleife werden beim laden der dateien falsche daten angezeigt....
    warum?!?

    (und brauche ich remove bevor ich die datei neu erstelle??)

    -brot



  • Deine write-Funktionen sind falsch. Hier mal ein Beispiel wie es aussehen sollte.

    size_t str_size = enter2.size();
    datei2.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size)); //Stringlänge brauchst du nachher für das Einlesen
    datei2.write(enter2.c_str(), str_size);
    


  • ich müsste also eine von beiden varianten wählen?
    wie funktioniert dann das auslesen?

    quelle2.read(reinterpret_cast<char*>(&out3), sizeof(out3));
    

    so?

    -brot



  • brot-knusprig schrieb:

    ich müsste also eine von beiden varianten wählen?

    Varianten? Du mußt sowohl die Größe als auch den Inhalt speichern, damit du später wieder an deine Daten herankommst.

    wie funktioniert dann das auslesen?

    Analog dazu - erst die Größe auslesen und dann den String-Inhalt:

    size_t str_size;
    quelle2.read(reinterpret_cast<char*>(&str_size),sizeof(str_size));
    out3.resize(str_size);
    quelle2.read(&out3[0],str_size);
    


  • Vorsicht, string macht nicht dieselben Zusicherungen was die Kontinuität der Daten angeht wie vector!



  • Punkt für dich - dann bleibt wohl als sichere Möglichkeit nur, einen Zwischenspeicher zu verwenden:

    size_t str_size;
    quelle2.read(reinterpret_cast<char*>(&str_size),sizeof(str_size));
    char* str_data = new char[str_size];
    quelle2.read(str_data,str_size);
    out3.assign(str_data,str_size);
    delete[] str_data;
    


  • Das einlesen funktioniert jetzt... jedoch ist beim Speichern ein Problem aufgetreten:

    1311335885683452545606724671234717114812066337360530535517850322123143438073451583919041137664075741408695380032997797693941515774560206746511801745944803272028082373781327597985875600530292778666649126180654062559672830333592535040000000000000000000000000000000000000;153  % } 2608734050659351532486483762591710908434176966764630657836323658471784724335337662313921225280404341471670442588095565182183140823302944372059039812523293461467814839629905920000000000000000000000000000   P `z3 9148103077779509614041854454197503032072210481948923307047310834996215483596048658185172

    Allerdings sollten normalerweise nur zwei Zahlen also z.B.

    12;13

    vorhanden sein und nicht allerlei unnötige zeichen (wie '}' '%' 'P')

    (betrifft enter2)

    remove(Zieldateiname1.c_str());
    			remove(Zieldateiname2.c_str());
    			datei1.open(Zieldateiname1.c_str(), ios::binary|ios::out), 
    			datei2.open(Zieldateiname2.c_str(), ios::binary|ios::out);
    			if(!datei2 && !datei1) {
    				system("CLS");
    				system("COLOR 0C");
    				cerr << "Error: Saving attempt failed! (17243)\n\n\n\a\a\a";
    				system("PAUSE");
    				exit(-1);
    			}
    			string enter2 = ((Nenner + ";") + Schritt);
    			size_t str_size = HauptZahl.size();
    			datei1.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size));
    			datei1.write(HauptZahl.c_str(), str_size);
    			str_size = enter2.size();
    			datei2.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size));
    			datei2.write(enter2.c_str(), str_size);
    			datei1.close();
    			datei2.close();
    			datei1.clear();
    			datei2.clear();
    

    -brot



  • Du speicherst doch binär. Logischerweise sind da komische Zeichen. Schau dir die Datei besser mal in einem Hexeditor an. Wenn du einlesen kannst ist alles ok.



  • ich hab mir alle strings nach dem einlesen ausgeben lassen - und da sind die zeichen auch...

    OUT3: 13113358856834525456067246712347171148120663373605305355178503221231434380
    73451583919041137664075741408695380032997797693941515774560206746511801745944803
    27202808237378132759798587560053029277866664912618065406255967283033359253504000
    0000000000000000000000000000000000;153  % } 2608734050659351
    53248648376259171090843417696676463065783632365847178472433533766231392122528040
    43414716704425880955651821831408233029443720590398125232934614678148396299059200
    00000000000000000000000000   P `z3 914810307777950961404185445419750303207221
    0481948923307047310834996215483596048658185172

    das ist was mich verwundert...



  • Dann zeige mal deine Einleseroutine.



  • Also ...
    1. std::remove brauchst du nicht. Setz einfach std::trunc als Öffnen-Parameter von std::ofstream.
    2. String schreiben:

    template<typename T>
    void write_string(std::basic_ostream<T>& out, std::basic_string<T> const& str)
    {
        if (!out) throw std::invalid_argument("stream invalid");
        std::size_t str_len(str.legth() + 1);
        out.write(reinterpret_cast<const T*>(&str_len), sizeof(std::size_t));
        out.write(str.c_str(), sizeof(T) * str_len);
    }
    

    3. String lesen:

    template<typename T>
    void read_string(std::basic_istream<T>& out, std::basic_string<T>& str)
    {
        if (!out) throw std::invalid_argument("stream invalid");
        std::size_t str_len(0);
        out.read(reinterpret_cast<char*>(&str_len), sizeof(std::size_t));
        T* arr_tmp(new T[str_len]);
        out.read(arr_tmp, str_len * sizeof(T));
        str = arr_tmp;
        delete [] arr_tmp;
    }
    

    ...

    @CStoll: Stimmt! 😛



  • (D)Evil schrieb:

    3. String lesen:

    Ich würde da ja eher einen basic_istream<T> verwenden, aber das ist deine Entscheidung 😉



  • ok, es funktioniert mittlerweile alles

    danke für eure hilfe


Anmelden zum Antworten