wstring zu string und zurück
-
Ich benutze in einem neuen Projekt zwei Bibliotheken von denen die eine wstring verwendet und die andere string. Weil ich auf Dauer nicht darum herum komme die beiden Typen ineinander zu konvertieren habe ich mir jetzt gleich zu Beginn zwei Funktionen dafür geschrieben.
Findet ihr diese Lösung gut oder würdet ihr das anders machen?
std::string narrow(const std::wstring& widen) { std::vector<wchar_t> wcs(widen.begin(), widen.end()); std::vector<char> mbs(widen.length()); std::wcstombs(&mbs[0], &wcs[0], widen.length()); return std::string(mbs.begin(), mbs.end()); } std::wstring widen(const std::string& narrow) { std::vector<char> mbs(narrow.begin(), narrow.end()); std::vector<wchar_t> wcs(narrow.length()); std::mbstowcs(&wcs[0], &mbs[0], narrow.length()); return std::wstring(wcs.begin(), wcs.end()); }
-
Die Quelle musst du doch nicht in nen vector stecken, da würde doch auch .c_str() funktionieren, oder?
-
Du hast recht! Danke!
// converts a wstring to a string std::string narrow(const std::wstring& wcs) { std::vector<char> mbs(wcs.length()); std::wcstombs(&mbs[0], wcs.c_str(), wcs.length()); return std::string(mbs.begin(), mbs.end()); } // converts a string to a wstring std::wstring widen(const std::string& mbs) { std::vector<wchar_t> wcs(mbs.length()); std::mbstowcs(&wcs[0], mbs.c_str(), mbs.length()); return std::wstring(wcs.begin(), wcs.end()); }So gefällt mir das schon deutlich besser, aber den anderen vector wird man wahrscheinlich nicht los, wenn man nicht new verwenden will.
-
// converts a wstring to a string std::string narrow(const std::wstring& wcs) { std::string mbs(wcs.length(), '\0'); std::wcstombs(&mbs[0], wcs.c_str(), wcs.length()); return mbs; } // converts a string to a wstring std::wstring widen(const std::string& mbs) { std::wstring wcs(mbs.length(), L'\0'); std::mbstowcs(&wcs[0], mbs.c_str(), mbs.length()); return wcs; }?
-
Das wäre natürlich die schönste Variante. Der Standard garantiert aber nicht, dass string seine Daten in einem festen Block speichert, weshalb &string[0] keine zuverlässige Lösung darstellt.
-
Ah richtig, da war doch was.
Dann schreib dir ein template zur compile-time-ueberpruefung des obigen Sachverhaltes (camper hatte afair mal darauf hingewiesen, dass man herausfinden kann, ob die string-implementierung den Speicher am Stueck haelt) und nutze dann diese Methode.....ODER:
lass es einfach so wie du es zuletzt hattest

-
Mich würde mal interessieren, was
c_str()zurückgibt, wenn der Speicher nicht an einem Stück ist. Denn wenn dafür extra ein neueschar-Array angelegt wird, wer soll dann für dessen Freigabe verantwortlich sein?
-
Bitte beantwortet die Frage von Nexus.
-
soweit ich weiß, ist ebenso wenig garantiert, dass der zurückgelieferte pointer nach einer weitern non-const operation auf der selben string instanz noch auf eienn verwendbaren speicherbereich zeigt. dh c_str könnte speicher allokieren, die adresse davon nicht nur zurückgeben, sondern auch intern speichern und bei der nächsten non-const operation auf diesem string den speicher wieder freigeben. ich _vermute_ aber, dass keine string implementierung das so krank macht und einfach intern einen normalen null-terminierten string verwendet und einfach den immer zurück gibt. wichtig ist aber, dass man das, was c_str zurück gibt, natürlich problemlos wie einen const char* verwenden kann. dort ist alles fix in einem stück.
-
besserwisser schrieb:
soweit ich weiß, ist ebenso wenig garantiert, dass der zurückgelieferte pointer nach einer weitern non-const operation auf der selben string instanz noch auf eienn verwendbaren speicherbereich zeigt.
Guter Einwand - das könnte einem tatsächlich Sorgen bereiten. Gerade weil
const char*oft auf Stringliterale zeigt, und diese statische Gültigkeitsdauer besitzen, könnte man da schnell in etwas reinreiten. Weiss jemand Genaueres darüber?