string in char* casten



  • Hallo Leute,

    1.) Situation
    zur Zeit habe ich ein Projekt am laufen, in dem u.a. ofstream und ifstream zum Einsatz kommen, um die Daten eines erstellten Profils in eine Binärdatei zu speichern und später wieder aufrufen zu können.
    Die Daten des Profils sind alle in einer Struktur (struct Profil) deklariert.
    Ich stelle kurz ein paar Ausschnitte des Codes aus meiner DLL (Data.dll) vor:

    //Data.h
    #pragma once
    #ifdef DATA_EXPORTS
    #define DATA __declspec (dllexport)
    #else
    #define DATA __declspec (dllimport)
    #endif
    #include <universal.h>
    
    struct DATA Profil
    {
    	string nickname;
    	string passwort;
    	string username;
    	string password;
    	string dateiname;
    	char anrede[4];
    	char vorname[30];
    	char nachname[30];
    	int alter;
    	char email_adresse[100];
    	void Erstellen(void);
    	void Speichern(void);
    	void Laden(void);
    	void System(void);
    };
    

    Zum Speichern und Laden der char und int daten verwende ich die folgenden Befehle. Funktionieren auch einwandfrei.

    //Data.cpp
    #include <universal.h>
    Profil Acc; // Erstellung einer Instanz (Acc).
    
    ...
    ... Hauptrountine und andere Funktionen
    ...
    
    void Profil::Save(void)
    {
    ...
    ...
    ...
    
            ofstream Save(Acc.dateiname.c_str(), ios::binary);
    	Save.write(Acc.anrede, sizeof (Acc.anrede));
    	Save.write(Acc.vorname, sizeof (Acc.vorname));
    	Save.write(Acc.nachname, sizeof (Acc.nachname));
    	Save.write(reinterpret_cast<char*> (&Acc.alter), sizeof (int));
    	Save.write(Acc.email_adresse, sizeof (Acc.email_adresse));
    	Save.close();
    
    ...
    ...
    ...
    }
    
    void Profil::Load(void)
    {
    ...
    ...
    ...
    
            ifstream Load (Acc.dateiname.c_str(), ios::binary);
    	Load.read(Acc.anrede, sizeof (Acc.anrede));
    	Load.read(Acc.vorname, sizeof (Acc.vorname));
    	Load.read(Acc.nachname, sizeof (Acc.nachname));
    	Load.read(reinterpret_cast<char*> (&Acc.alter), sizeof (int));
    	Load.read(Acc.email_adresse, sizeof (Acc.email_adresse));
    	Load.close ();
    
    ...
    ...
    ...
    }
    

    Wie ihr gut sehen könnt speichere ich die char daten ganz normal ab und die int daten caste ich mit dem C++ reinterpret_cast Operator nach char*.

    folgendes Problem:
    aber wie und womit caste ich die >string-daten< nach char* ? sodass ich sie ordnungsgemäß abspeichern und wieder aufrufen kann. Denn bei string da zieht diese reinterpret_cast methode nicht ^^ ...
    Danke schonmal im Voraus!



  • Meinst du mit "string Daten" std::string? Falls ja, dann kannst du das mit der Memberfunktion c_str() lösen. Also z.B.

    std::string foo = "bar";
    foo.c_str(); // wäre dann char*
    

    Allerdings kannst du std::string auch einfach in eine Datei schreiben ohne ihn Umzuwandeln. Das ginge mit

    std::ofstream of ("foo.txt");
    of << foo << "\n"; // fügt noch einen Zeilenumbruch ein, macht es einfach die Datei wieder einzulesen
    

    Have fun!



  • jo, also hasts schon erfasst - std:string meine ich auch;

    NUR das problem ist, c_str() ist ein <const char*>-Element und an der stelle mukkt auch mein Compiler rum, dass es ich const char* nicht nach char* konvertieren kann

    Fehler	1 error C2664: 'std::basic_istream<_Elem,_Traits>::read': Konvertierung des Parameters 1 von 'const char *' in 'char *' nicht möglich
    


  • Nun, wenn du die Daten nicht verändern möchtest, solltest du das const mit Hilfe eines const_cast wegbekommen. Aber das erlaubt nicht die Daten zu verändern, sondern kann lediglich helfen die Compilerfehler zu umgehen. Ansonsten könntest du die Strings aber wie gesagt auch einfach so in die Datei schreiben.



  • OK, thanks man. Jetzt funzt das korrekt 😉



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • basti33 schrieb:

    Nun, wenn du die Daten nicht verändern möchtest, solltest du das const mit Hilfe eines const_cast wegbekommen. Aber das erlaubt nicht die Daten zu verändern, sondern kann lediglich helfen die Compilerfehler zu umgehen. Ansonsten könntest du die Strings aber wie gesagt auch einfach so in die Datei schreiben.

    Sach mal, ist eigentlich "internationale cast-Schmuddelwoche" ?

    Alle Welt gräbt sich tiefe und häßliche Gruben mit Rumcasten statt mit sauberen Lösungen.
    Wenn ein char* erwartet wird, ist es doch ein Leichtes, einen solchen zur Verfügung zu stellen...

    struct string_copy {
       string& orig;
       char* cpy;
       string_copy(string& s) : orig(s), cpy(new char[s.length() + 1]) {
          copy(orig.begin(), orig.end(), cpy);
          cpy[orig.length()] = '\0';
       }
       char* operator() { return cpy; }
       ~string_copy() { 
          copy(cpy, cpy + orig.length(), &orig[0]);
          delete[] cpy;
       }
    };
    
    ...
       string s = "Juppi";
       {
          string_copy cpy(s);
          char_stern_Funktion(cpy);
       }
    ...
    

    (Lösungsskizze)
    Kann man noch um 100 tolle Features erweitern, aber das klappt so schonmal und ist sicher (im Rahmen der "üblichen char*-Sicherheit");

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Alle Welt gräbt sich tiefe und häßliche Gruben mit Rumcasten statt mit sauberen Lösungen.

    Was genau ist denn an diesem const_cast nun so schlimm?


  • Administrator

    basti33 schrieb:

    Was genau ist denn an diesem const_cast nun so schlimm?

    Wenn er nun sowas macht, was er ja auch tut (Fehlermeldung lesen):

    // ...
    ifstream Load (Acc.dateiname.c_str(), ios::binary);
    
    Load.read(const_cast<char*>(Acc.nickname.c_str()), sizeof(Acc.nickname));
    
    // Dann ist das undefiniertes Verhalten und völliger Scheiss.
    

    Grüssli



  • Sach mal, ist eigentlich "internationale cast-Schmuddelwoche" ?

    Hab ich mich auch schon gefragt. Scheint ein beliebtes Mittel zu sein um Compiler Errors zu beheben.


Anmelden zum Antworten