std::string in char*



  • LordJaxom schrieb:

    Ich lese immer wieder dass string weder garantiert, dass die Daten an einem Stück im Container liegen müssen

    Ich denke aber schon, dass dies der Fall ist. Oder wie erklärst du dir Funktion data()? Zudem muss std::basic_string den Anforderungen einer Sequenz entsprechen.

    LordJaxom schrieb:

    noch dass die Daten im Container schon nullterminiert sind.

    Davon hat auch niemand gesprochen. Ich weiss schon, man verbindet char* sofort mit C-String, das ist aber nicht wirklich korrekt. Ein C-String wird nunmal durch char* repräsentiert, char* ist jedoch nicht gleichzusetzen mit C-String.


  • Mod

    groovemaster schrieb:

    LordJaxom schrieb:

    Ich lese immer wieder dass string weder garantiert, dass die Daten an einem Stück im Container liegen müssen

    Ich denke aber schon, dass dies der Fall ist. Oder wie erklärst du dir Funktion data()? Zudem muss std::basic_string den Anforderungen einer Sequenz entsprechen.

    der standard ist so formuliert, dass eine derartige implementation (daten an einem stück und nullterminiert) eine offensichtliche wahl ist. der sequenzaspekt erfordert das aber nicht, auch deque bildet sequenzen. außerdem macht der standard keine explizite aussage über die komplexität der data und c_str memberfunktionen. prinzipiell ist es denkbar, dass die entsprechenden arrays erst beim aufruf konstruiert werden.

    groovemaster schrieb:

    Ich denke aber schon, dass dies der Fall ist.

    was meinst du? dass der standard das garantiert, oder das jede existierende implmentation sich so verhält?



  • groovemaster schrieb:

    Davon hat auch niemand gesprochen. Ich weiss schon, man verbindet char* sofort mit C-String, das ist aber nicht wirklich korrekt. Ein C-String wird nunmal durch char* repräsentiert, char* ist jedoch nicht gleichzusetzen mit C-String.

    Ich ging dreisterweise 😉 davon aus, da der OP mit strcpy arbeitete, welches zum einen auf die nullterminierung der Quelle angewiesen ist und zum anderen selbst das Ziel nullterminiert.



  • camper schrieb:

    was meinst du? dass der standard das garantiert, oder das jede existierende implmentation sich so verhält?

    Dass jede existierende Implementation sich so verhält. Eine Garantie ist mir seitens des Standards jedenfalls nicht bekannt.



  • groovemaster schrieb:

    camper schrieb:

    was meinst du? dass der standard das garantiert, oder das jede existierende implmentation sich so verhält?

    Dass jede existierende Implementation sich so verhält. Eine Garantie ist mir seitens des Standards jedenfalls nicht bekannt.

    Bei der Programmierung sollte man sich darauf beschränken, was der Standard definiert. Daß die existierenden Impelentationen eine gewisse Eigenschaft hat (habt ihr auch alle exisitiernden C++-Compiler getestet?), garantiert nicht, daß die nächste Version dieses Verhalten zeigt.

    Im übrigen sollte man beachten, daß ein std::string häufig Referenzgezählt ist und daher eine Veränderung der Daten nicht zu empfehlen ist. Es hat schon seinen Grund, warum die data()-Methode einen const-Zeiger liefert.

    Im übrigen hat die Originallösung noch einen Fehler. std::string::size() liefert die Länge des Strings. Ein strcpy des c_str()-Zeigers kopiert aber ein Zeichen mehr. Ihr habt den Nullterminator vergessen, welcher von c_str() garantiert wird, aber nicht zur Stringlänge gehört.

    Tntnet



  • template <typename CharT>
    std::auto_ptr<CharT> string_to_array (const std::basic_string<CharT>& str)
    {
        CharT* cstr = new char[str.size () + 1];
        std::copy (str.begin (), str.end (), cstr);
        cstr[str.size ()] = 0;
        return std::auto_ptr<CharT> (cstr);
    }
    

    Das erspart das (möglicherweise ineffiziente) Gefrickel mit c_str oder data.



  • Du hast da ein +1 vergessen.



  • Das solltest Du nochmal überdenken...



  • Statt

    std::copy (str.begin (), str.end (), cstr);
    

    geht auch

    str.copy(cstr, str.size());
    

    Tntnet


  • Mod

    .filmor schrieb:

    template <typename CharT>
    std::auto_ptr<CharT> string_to_array (const std::basic_string<CharT>& str)
    {
        CharT* cstr = new char[str.size () + 1];
        std::copy (str.begin (), str.end (), cstr);
        cstr[str.size ()] = 0;
        return std::auto_ptr<CharT> (cstr);
    }
    

    Das erspart das (möglicherweise ineffiziente) Gefrickel mit c_str oder data.

    array new und auto_ptr? keine gute idee.



  • tntnet schrieb:

    Bei der Programmierung sollte man sich darauf beschränken, was der Standard definiert.

    Naja, mit dieser Einstellung wirst du in der Praxis aber schnell an Grenzen stossen. Es geht ja nicht darum, dass irgendetwas Verbotenes gemacht werden soll.

    tntnet schrieb:

    Im übrigen sollte man beachten, daß ein std::string häufig Referenzgezählt ist und daher eine Veränderung der Daten nicht zu empfehlen ist.

    Was meinst du mit "eine Veränderung der Daten nicht zu empfehlen ist"? Du kannst jedes String Objekt ganz normal per op [] ändern.



  • groovemaster schrieb:

    Was meinst du mit "eine Veränderung der Daten nicht zu empfehlen ist"? Du kannst jedes String Objekt ganz normal per op [] ändern.

    Er meinte höchstwahrscheinlich die Änderung der Daten in (char*)&str[0] oder const_cast<char*>(str.data()), also das worum es in diesem Thread die meiste Zeit ging 😉



  • Wenn es um das const wegcasten ging, dann würde aber das "nicht zu empfehlen" nicht passen. 😉 Denn dann wäre es schlichtweg falsch.



  • camper schrieb:

    array new und auto_ptr? keine gute idee.

    Izz, stimmt. Dann halt mit normalem Zeiger:

    template <typename CharT>
    CharT* string_to_array (const std::basic_string<CharT>& str)
    {
        CharT* cstr = new char[str.size () + 1];
        std::copy (str.begin (), str.end (), cstr);
        cstr[str.size ()] = 0;
        return cstr;
    }
    

    Ich wollte dem Anwender Arbeit abnehmen.
    BTW, beim Test hatts wohl nur deshalb nicht gekracht, weil die Benutzung so aussah:

    std::cout << string_to_array (std::string ("asdf")).release () << std::endl;
    

    😃


Anmelden zum Antworten