string.c_str() und char *



  • Hi,

    std::string.c_str() liefert mir ja einen const char *, was auch ok ist.

    Nun brauch ich allerdings gezwungener maßen einen char *.
    Mir fallen auf anhieb zwei Wege ein, einer davon ist wohl ziemlich schlecht und zwar das const wegcasten.

    Der andere wäre wohl ein strcpy, wenn ich das richtig verstehe.

    Gibt es noch andere Möglichkeiten? char * darf bei mir nicht const sein.

    Nochwas: Für strcpy muss der speicher in der passenden Größe bereits alloziiert sein, dass ist doch richtig, oder?



  • Wieso darf das char* nicht konst sein? Wird es definitiv geändert?



  • Wenn die Antwort auf Tachyons (zweite) Frage "ja" lautet:

    Du kannst statt eines manuell allokierten Puffers std::vector nehmen, der übernimmt die Aufgabe der Allokation für Dich. Den String in diesen Puffer zu kopieren geht dann wiederum in zwölf verschiedenen Varianten. Hier sind zwei:

    vector<char> buffer( str.begin(), str.end() );
    buffer.push_back( '\0' ); // nullbyte dranhängen
    
    // oder
    
    vector<char> buffer( str.c_str(), str.c_str() + str.size() + 1 ); // erzeugung aus c_str, +1 wegen dem Nullbyte
    
    // benutzen:
    
    char* c_buffer = &buffer[0];
    


  • Tachyon, keine Ahnung, aber der Teil wird generiert und nicht von mir, daher habe ich keinen Einfluss drauf.

    Zu dem vector: Warum muss der Null Terminator eigentlich dran? Wenn ich ein char * alloziiere, muss da auch keiner hin, oder?



  • Seikilos schrieb:

    Zu dem vector: Warum muss der Null Terminator eigentlich dran? Wenn ich ein char * alloziiere, muss da auch keiner hin, oder?

    c-strings sind immer nullterminiert.



  • Seikilos schrieb:

    Tachyon, keine Ahnung, aber der Teil wird generiert und nicht von mir, daher habe ich keinen Einfluss drauf.

    Zu dem vector: Warum muss der Null Terminator eigentlich dran? Wenn ich ein char * alloziiere, muss da auch keiner hin, oder?

    Für C-Strings muss der immer mit rein. Sofern irgendwas mit C-Strings arbeitet, wird die Länge des Strings immer über Such nach dem terminierenden 0-Zeichen ermittelt.
    Auch wenn Du manuell Speicher für z.B. 10 sichtbare Zeichen allokierst, brauchst Du insgesamt 11 Zeichen, wegen der 0-Terminierung.



  • Seikilos schrieb:

    Zu dem vector: Warum muss der Null Terminator eigentlich dran? Wenn ich ein char * alloziiere, muss da auch keiner hin, oder?

    Wenn es sich um binäre Daten handelt, die mit Längenangaben übergeben werden, dann muss natürlich kein zusätzlicher Nullterminator dran. Da Du aber selbst von strcpy gesprochen hast, nahm ich an, es geht um C-Strings. Und die sind, ja, immer nullterminiert.

    (Und wenn Du den Platz fürs Nullbyte nicht reservierst und anschließend strcpy benutzt, hast Du einen klassischen Buffer Overflow, verursacht durch einen off-by-one-Fehler)



  • Danke für die Erklärung.

    Sollte man dann strcpy_s fürs Kopieren benutzen? benutzen?



  • Seikilos schrieb:

    Danke für die Erklärung.

    Sollte man dann strcpy_s fürs Kopieren benutzen? benutzen?

    Wenn Du willst, dass Dein Code Standardkonform ist, nein.



  • Seikilos schrieb:

    Sollte man dann strcpy_s fürs Kopieren benutzen? benutzen?

    Kenn ich nicht, was soll das sein?

    (Ok, ich gebe zu, ich kenne strcpy_s doch. Aber die Tatsache, dass ich es zu leugnen versuche, sollte Dir die Frage bereits beantworten. Im Zweifel schau immer nach, ob die Funktion zu Standard C++ gehört. Microsoft-Erweiterungen gehören nicht dazu.)



  • Wenn du stumpf kopieren willst (ohne Nullbyte) und dir die Länge bekannt ist, kannst du std::memcpy verwenden oder besser: std::copy


Anmelden zum Antworten