String vs. char* vs. const char*



  • Ups, bin wirklich im falschen Forum 🙄.

    Wie gesagt, kämpfe noch ziemlich mit strings und char* und weiß nicht genau, wann man was verwenden soll, aber sag mir bitte, warum das unnötig und langsam ist. Wie macht man es richtig?

    mfg,
    soad



  • Wenn du einen String via Call-By-Value, also via:

    void func (std::string str)
    {
    }
    

    übergibst, wird der komplette Originalstring in den neuen String "str" kopiert (und das dauert). Besser bei größeren Objekten also Call-By-Ref verwenden:

    void func (std::string& str)
    {
    }
    

    Jetzt wird der String nicht mehr kopiert. Er bekommt nur innerhalb von func() den neuen Aliasnamen "str". Allerdings würden sich jetzt auch alle Änderungen auf den Original-String auswirken - wird ja nicht mit einer Kopie gearbeitet. Um das zu verhindern kann man Änderungen verbieten:

    void func (const std::string& str)
    {
    }
    

    Dank std::string benötigst du als Anfänger erstmal gar kein Wissen rund um char*, etc. Dir wird dann im Kapitel über Arrays ein Lichtlein aufgehen was ein String in C früher war und immer noch sein kann - nichts mehr als ein Array von Zeichen.

    MfG SideWinder



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET 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.



  • ok, danke!

    Zu meinem "Problem": der char* ist nicht leer, sondern enthält nur das erste Zeichen.

    Einen String übergebe ich eigentlich nur, weil ich zeilenweise mittels getline() einlese, oder könnte man das auch mit char* einfach lösen?

    mfg,
    soad



  • soad schrieb:

    ...könnte man das auch mit char* einfach lösen?

    mfg,
    soad

    lösen: Ja
    einfach: Nein

    Einfacheres als string findest Du nicht. 😃

    Gruß,

    Simon2.



  • void foo(string input)
    {
       cout << input << endl;   // String ist gefuellt
    
       const char* bar = input.c_str();
    
       cout << bar << endl;      // Nur das 1.Zeichen :( ?!?
    }
    

    es hat bi mir funktioniert



  • const char* gewinnt



  • So da sich kein anderer erbarmt hir Mal die Lösung für dein Problem. Ich hatte ein ähnliches, wodurch ich in diesem Fall Abstand von c_str() genommen habe:

    void foo(std::string cInput)
    {
        std::cout <<cInput<<" dies ist der \"string\"<<"\n";
        char *cBuffer=new char[cInput.length()];
        strcpy(cBuffer,cInput.c_str());
        std::cout <<cBuffer<<" dies ist der \"char*\"<<"\n";
    }
    

    Müsste eigentlich soweit funktionieren. Probier es aus.



  • netrobot schrieb:

    void foo(string input)
    {
       cout << input << endl;   // String ist gefuellt
       
       const char* bar = input.c_str();
    		
       cout << bar << endl;      // Nur das 1.Zeichen :( ?!?
    }
    

    es hat bi mir funktioniert

    Das Problem war, dass ich zuvor noch strtok() verwendet habe, ganz nachvollziehen kann ich es zwar noch nicht, aber ich hab es jetzt zumindestens (etwas unschön) gelöst ;).

    Kevinus schrieb:

    So da sich kein anderer erbarmt hir Mal die Lösung für dein Problem. Ich hatte ein ähnliches, wodurch ich in diesem Fall Abstand von c_str() genommen habe:

    void foo(std::string cInput)
    {
        std::cout <<cInput<<" dies ist der \"string\"<<"\n";
        char *cBuffer=new char[cInput.length()];
        strcpy(cBuffer,cInput.c_str());
        std::cout <<cBuffer<<" dies ist der \"char*\"<<"\n";
    }
    

    Müsste eigentlich soweit funktionieren. Probier es aus.

    Danke, schaut eigentlich jetzt eh nicht so kompliziert aus und es funkt 👍!



  • soad schrieb:

    netrobot schrieb:

    void foo(string input)
    {
       cout << input << endl;   // String ist gefuellt
       
       const char* bar = input.c_str();
    		
       cout << bar << endl;      // Nur das 1.Zeichen :( ?!?
    }
    

    es hat bi mir funktioniert

    Das Problem war, dass ich zuvor noch strtok() verwendet habe, ganz nachvollziehen kann ich es zwar noch nicht, ...

    Das mit dem strtok() ist die wesentliche Information dabei.
    Gemäß Schnittstelle garantiert sttok() nicht, dass es nicht doch versucht, den String, den es "tokenized" zu verändern.
    c_str() garantiert aber nur das erwartete ergebnis, solange der String unverändert bleibt ... deswegen gibt er auch einen const char* zurück (und nicht einen char* ).
    Der von Kevinus gezeigte Weg ist kein "Hack", sondern der kanonische Weg, zwischen einem String und einem veränderbaren char-Buffer zu vermitteln: Kopieren eben.
    (Allerdings ht er einen kleinen aber typischen Fehler drin - derseleb unterläuft mir auch immer:

    Kevinus schrieb:

    ...
        char *cBuffer=new char[cInput.length()+1]; // Ein Zeichen für "Nullbyte"
    

    ...

    Außerdem sollte der Speicher mit delete[] nach Gebrauch wieder freigegeben werden - die new/copy/delete-Kiste ist ein gutes Beispiel dafür, warum man besser string in seinen SChnittstellen verwenden sollte 😃 )

    Ist nicht besonders erstaunlich eigentlich, weil auch niemand auf die Idee käme, andere Typen würden eine "kopiefreie Konvertierung" überleben:

    void quadriere(int*);
    
    int main() {
       char s[] = "123";
       quadriere((int*) s); // wer erwartet, dass das klappt ?
    ...
    

    Ebensowenig ist das mit string->char* erstaunlich - es ist eher erstaunlich, dass es überhaupt bei einigen wenigen Typen funktioniert (ich wäre aber immer sehr skeptisch, ob das gutes Design ist).

    Gruß,

    Simon2.


Anmelden zum Antworten