Unicode String zu std::string
-
Eigentlich wäre die sauberste Lösung alle sdt:string zu std:wstring abzuändern.
Dann passt der wchar_t*
-
MichelRT schrieb:
Eigentlich wäre die sauberste Lösung alle sdt:string zu std:wstring abzuändern.
Dann passt der wchar_t*Wenn man die Daten aber im AnsiFormat speichern oder übertragen muss, kommt man aber um eine weitere Konvertierung in std::string nicht herum.
Die Variante mit dem AnsiString-Konstruktor hat den Vorteil, dass sie vom Builder plattformübergreifend unterstützt wird, man muss nicht die WinAPI (WideCharToMultiByte) bemühen. Auch funktioniert das ganz ähnlich mit Utf8String statt AnsiString.
Trotzdem missfällt mir dabei, dass ein dritter Stringtyp ins Spiel kommt und die Daten ein zusätzliches Mal kopiert werden.
Hätte eigentlich erwartet, dass einer der Experten mit einer coolen C++11 Lösung kommt, die direkt vom .c_str() des UnicodeStrings in einen std::string konvertiert. Lösungen wie die hier, benötigen immer noch einen std::vector, weil man nicht in den Speicher von std::string schreiben soll, da kann man auch beim AnsiString bleiben:
std::string narrow(std::wstring const& text) { std::locale const loc(""); wchar_t const* from = text.c_str(); std::size_t const len = text.size(); std::vector<char> buffer(len + 1); std::use_facet<std::ctype<wchar_t> >(loc).narrow(from, from + len, '_', &buffer[0]); return std::string(&buffer[0], &buffer[len]); }
-
nn schrieb:
Hätte eigentlich erwartet, dass einer der Experten mit einer coolen C++11 Lösung kommt, die direkt vom .c_str() des UnicodeStrings in einen std::string konvertiert.
Schon mal probiert einen vollen 40 Personen besetzten Bus in ein Auto zu stopfen ohne das einer draussen stehen bleibt?
Genau dass kann passieren bei der Umwandlung von UnicodeString nach AnsiString bzw std::string
UnicodeString und std:wstring sind wchar_t mit 2 Byte
AnsiString und std:string sind char mit 1 Byte
-
nn schrieb:
Die Variante mit dem AnsiString-Konstruktor hat den Vorteil, dass sie vom Builder plattformübergreifend unterstützt wird...
Das ist der Grund warum ich diese Variante gerne beibehalten möchte.
-
holla schrieb:
UnicodeString und std:wstring sind wchar_t mit 2 Byte
AnsiString und std:string sind char mit 1 ByteOhh, das wusste ich auch noch nicht. Danke für den Hinweiß
-
holla schrieb:
nn schrieb:
Hätte eigentlich erwartet, dass einer der Experten mit einer coolen C++11 Lösung kommt, die direkt vom .c_str() des UnicodeStrings in einen std::string konvertiert.
Schon mal probiert einen vollen 40 Personen besetzten Bus in ein Auto zu stopfen ohne das einer draussen stehen bleibt?
Genau dass kann passieren bei der Umwandlung von UnicodeString nach AnsiString bzw std::string
UnicodeString und std:wstring sind wchar_t mit 2 Byte
AnsiString und std:string sind char mit 1 ByteGenau deshalb habe ich geschrieben, dass alles durchgängig mit wstring die sauberere Lösung wäre.
-
nn schrieb:
Wenn man die Daten aber im AnsiFormat speichern oder übertragen muss, kommt man aber um eine weitere Konvertierung in std::string nicht herum.
Dann frage ich mich wieso kommen die Daten dann hier als Unicodestring an und nicht schon im AnsiFormat. Da ist dann schon vorher etwas schief gelaufen
-
holla schrieb:
Schon mal probiert einen vollen 40 Personen besetzten Bus in ein Auto zu stopfen ohne das einer draussen stehen bleibt?
Geht ganz einfach
std::wstring w = L"Holla die Waldfee"; std::string s(w.begin(), w.end());
Wo ist das Problem ?
holla schrieb:
Genau dass kann passieren bei der Umwandlung von UnicodeString nach AnsiString bzw std::string
Rat mal, was der Unterstrich da macht ?
std::use_facet<std::ctype<wchar_t> >(loc).narrow(from, from + len, '_', &buffer[0]);
holla schrieb:
UnicodeString und std:wstring sind wchar_t mit 2 Byte
Zum Glück haben auch die C++ Builder Entwickler daran gedacht, dass auf manchen der Zielplattformen wchar_t vier Bytes groß ist.
holla schrieb:
...
Trotz dieses Gesülzes gibt es wohl tatsächlich eine C++11 Lösung ohne Zwischenkopieren
http://en.cppreference.com/w/cpp/locale/wstring_convert/to_bytesMichelRT schrieb:
Dann frage ich mich wieso kommen die Daten dann hier als Unicodestring an und nicht schon im AnsiFormat. Da ist dann schon vorher etwas schief gelaufen
Da ist nichts schiefgelaufen, das ist schlicht die Realität. Wenn man aus seiner schönen Unicode Anwendung mit externen Geräten z.B. über serielle Schnittstelle oder Netzwerk reden will und diese nur Ansi oder Utf8 reden. Irgenwie müssen da ja auch mal Benutzereingaben weitergeleitet oder angezeigt werden.
-
na dann probier mal イクルウェアショッ
UnicodeString Test="イクルウェアショッ";
in einen AnsiString bzw std::string zu stopfen!
-
hola schrieb:
in einen AnsiString bzw std::string zu stopfen!
Gibt halt, im obigen Beispiel, entsprechend viele Unterstriche.
Warum sollte wegen dir ein Gerät an der seriellen Schnittstelle plötzlich japanisch sprechen ?
-
Zero01 schrieb:
Das ist der Grund warum ich diese Variante gerne beibehalten möchte.
Kannst du ja auch. Nur wenn da sehr viele Strings umgewandelt werden, sollte man sich Gedanken wegen dieses doppelten Kopierens von UnicodeString nach AnsiString nach std::string machen.
-
Warum will wohl ein Japaner dass seine eingegebenen Japanischen Zeichen auch auf der anderen Seite als Japanische Zeichen ankommen?
Wenn diese in einen AnsiString reingedrückt werden sind diese nunmal SCHROTT.
Scheinbar bist du noch nicht in den Genuss gekommen eine Unicode Mehrspachenanwendung zu entwickeln die Weltweit eingesetzt werden soll.
-
holla schrieb:
Warum will wohl ein Japaner dass seine eingegebenen Japanischen Zeichen auch auf der anderen Seite als Japanische Zeichen ankommen?
Wenn du was sagen willst, sag es. Aber schlag vorher mal im Wörterbuch nach, was narrow auf deutsch heißt.
Das es verlustbehaftete Zeichenkonvertierungen geben könnte, scheint dir noch nicht in den Sinn gekommen zu sein. Das solche Verluste sprachabhängig sind ist der Grund warum da in C++ locales und facets gebraucht werden.
Sinnigerweise kommunizieren meine Unicode-Anwendungen mit Industrie-Steuerungen gleich zweier japanischer Hersteller. Nur ist das den Steuerungen im Normalfall egal, die wollen ihren Text als Ansi. Deswegen gibt es unterschiedliche String-Welten in der Software. Gelegentlich müssen dabei Grenzen überschritten werden.
Natürlich wird der Text dabei auf unerlaubte Zeichen kontolliert.Also Holla, jetzt mal Butter bei die Fische. Deshalb steht ihr Piraten doch bei 2 Prozent. Du bist da, hast irgendwas wichtiges zu sagen, kannst es aber nicht artikulieren. Nur irgenwas japanisches, was meinen japanischen SPSsen und Robotern aber egal ist.
-
Wenn die angesteuerten Geräte nur AnsiString bzw. ASCII verstehen und in deiner Anwendung nie Unicodezeichen eingegeben werden bzw. übertragen werden, dann gibt es doch auch keine Unicodeumwandlungsprobleme!
In meinen Anwendungen muß ich UnicodeStrings verwenden und diese natürlich auch verlustfrei speichern/weiterverarbeiten und übergeben z.B. per UTF8.
Was soll mit den Piraten sein? ka ist mir egal
Bei deinen japanischen SPSen und Roboter werden sicher keine Unicodezeichen dargestellt? oder doch?
-
holla schrieb:
Wenn die angesteuerten Geräte nur AnsiString bzw. ASCII verstehen und in deiner Anwendung nie Unicodezeichen eingegeben werden bzw. übertragen werden, dann gibt es doch auch keine Unicodeumwandlungsprobleme!
Mann, darum geht es doch in diesem Thread. Der Fragesteller wechselt auf einen neueren C++ Builder. Er hat früher Ansi gesendet, die Gegenseite dürfte das immer noch erwarten. Er kann doch nicht einfach wchar_t senden, schon wegen den Nullen darin, der Byteorder und weil man sowieso bei Netzwerkverbindungen meist UTF-8 verwenden würde.
Damit bin ich auch wieder bei meinen japanischen Steuerungen, wenn dann nehmen die in bestimmten Fällen UTF-8.
Das führt mich aber wieder zu meinen Effizienzüberlegungen. Ich hab z.B. in einem Edit in der Oberfläche einen Text, meinetwegen japanisch. Wenn die Netzwerk-API std::string will, kann sie ja, wenn sie byteorientiert ist, muss ich von UnicodeString nach Utf8String nach std::string, habe also jeden String dreimal. Dieser zweite Teil des Problems hat also gar nix mit Unicode zu tun.
Darum meine Nachfrage, weil meine Lösung den Fragesteller befriedig, mich aber nicht: Wie komme ich in einem Schritt dahin. Zumindest von std::wstring zu std::string (mit UTF-8 Inhalt), habe ich mittlerweile die Antwort selbst gefunden (std::wstring_convert<> erspart den std::vector<char> bei Verwendung von std::wcstombs).
An beiden Punkten, um die es eigentlich ging, hast du konsequent vorbei diskutiert.
-
Eigentlich wollte ich nicht vorbei diskutieren sondern nur wie auch MichelRT darauf hinweisen, daß mit Verlusten zu rechnen ist bzw. evtl. gibt es ja schon für die "Gegenstellen" was WideString/UTF8'iges um dem 'Verlust' gegenzuwirken.
Machst du deine Umwandlung so?
std::string sString = UTF8String(Edit1->Text).c_str();
Glaube gibt keinen direkteren Weg als den.
-
Immerhin dürfte auch dem Fragesteller jetzt klar geworden sein, dass in Unicode-Anwendungen die Dinge komplizierter sind.
Insbesondere wenn man noch die Cross Plattform Ambitionen des C++ Builder in Betracht zieht.
holla schrieb:
Machst du deine Umwandlung so?
std::string sString = UTF8String(Edit1->Text).c_str();
Glaube gibt keinen direkteren Weg als den.
Nein, mein Bibliothekscode muss auch mit Visual Studio laufen. C++ Builder ist nur noch für Altprojekte. Also entweder WinApi oder über den C++ Weg.
-
nn schrieb:
Immerhin dürfte auch dem Fragesteller jetzt klar geworden sein, dass in Unicode-Anwendungen die Dinge komplizierter sind.
Ja, allerdings habt ihr mir aufgezeigt wie einige Fälle nun zu behandeln sind und wo Fehler entstehen können. Da es in meiner Anwendung lediglich zu konvertierende Befehle in English sind, kann ich diese Lösung auch beibehalten. Ich halte mir die von euch erläuterten Probleme, die von Unicode zu AnsiString entstehen können, im Hinterkopf.
Ich danke euch herzlichst für die regen Teilnahme an meiner Frage!