std::vector<char> nach std::string terminiert nicht bei Null-byte
-
Hallo,
noch ein kleines Problem: Ich muss aus einer legacy C-API einen null-terminierten C-String aus einem Speicherereich vorgegebener Länge einlesen. In miner Applikation ist das ganze natürlich ein std::string.
Die Funktion, die mir den null-terminierten C-String gibt, erwartet einen char* und eine Länge.
Der String kann bis zu 256 characters lang sein und ich habe keine Möglichkeit vorher zu wissen, wie lang das ding wirklich ist, also wo das Null-byte steht.
Mein Ansatz daher:
std::vector<char> vc; vc.resize(256); legacy_c_funktion(&(vc[0]), 256); std::string str(vc.begin(), vc.end());Das hat leider zur Folge, dass dann str ein String ist, der immer 256 Zeichen hat, wo vorne das gewünschte drin steht und danach nur noch Whitespace.
Daraufhin habe ich mir ein paar trim()-Funktion für std::string angeguckt, aber leider liefert sowohl boost::algorithm::trim als auch diverse andere selbstkodierte trim-Funktionen immer den String mit whitespaces zurück, was mich vermuten lässt, dass das was ich als whitespace angezeigt bekomme, gar kein whitespace ist, sondern was anderes nicht darstellbares.Also: Wie stelle ich sicher, dass beim kopieren des char-vectors in den String beim 0-char auch tatsächlich terminiert wird??
Philipp
-
std::vector<char> vc; vc.resize(256); legacy_c_funktion(&(vc[0]), 256); std::string str(vc.begin(), std::find(vc.begin(), vc.end(), 0));
-
Dürfte nicht auch ein
std::string str(&vc[0]);reichen? Der Konstruktor von String sollte den Vector dann als nullterminiertes char-Array interpretieren.
-
Oder einfach so:
std::string str(&(vc[0]));
-
Boah, Facepalm!!!!! Danke. Hab heute schon zu lange programmiert

-
Mein Vorschlag:
char vc[256]; // reserve 256 bytes on the stack legacy_c_funktion(vc, 256); // fill them with legacy_c_funktion vc[sizeof vc - 1] = 0; // ensure vc is however '\0' terminated std::string str(vc); // copy significant data from stack to the heapGruß Frank
-
sizeof(vc) wird aber immer 256 zurückgeben. D.h. das immer alle Zeichen des Arrays interpretiert werden. Deshalb steht dann in dem string nach dem eigentlichen Inhalt undefinierte Zeichen.
-
Hallo player4245,
klar:
vc[sizeof vc - 1] = 0;setzt nur ein nullbyte ans Ende von vc, also das 256te Zeichen wird null.
eine
legacy_c_funktion(vc, 256);muss jedoch auch ein Nullbyte ans Ende der signifikaten Zeichen setzen
um die Länge der Zeichekette zu signalisieren.
Davon sind auch alle anderen Vorschläge ausgegangen.Einziger Sonderfall, wenn die Anzahl signifikater Zeichen >= 256 Zeichen ist.
Hier gibts es in C Funktionen, die kein null byte mehr schreiben - warum auch immer. Eine nachfolgende Suche/Kopie (std::string str(vc)) bis zum Nullbyte führt dann zu UB.vc[sizeof vc - 1] = 0;kann entfallen, wenn die legacy_c_funktion zweifelsfrei,
auch in der Grenzsituation, null terminiert.Gruß Frank
-
Warum nicht gleich initialisieren?
char vc[256] = {};