Unicode String zu std::string
-
...
-
Swordfish schrieb:
Zero01 schrieb:
Erst als AnsiString casten und als c_str() übergeben funktioniert. Komisches Konstrukt
Zeig' mal.
Sorry, ich lag falsch. Ist natürlich kein Cast sondern jediglich ein Funktionsaufruf mit Rückgabetyp AnsiString:
AnsiString( Command ).c_str()
-
Zero01 schrieb:
Sorry, ich lag falsch. Ist natürlich kein Cast sondern jediglich ein Funktionsaufruf mit Rückgabetyp AnsiString:
Das ist eher ein Aufruf eines Konstruktors von AnsiString. Das dabei erzeugte temporäre Objekt gibt über c_str() einen const char* zurück, welcher dann weiter in ein std::string umgewandelt wird.
-
Zero01 schrieb:
Allerdings habe ich noch ein Problem mit dem "neuen" TcpClient, der seit dem BCB 2006 Einzug gehalten hat. Jeder Versuch zu connecten scheitert mit dem Socket Error 10035. Irgendwie scheint das Socket nicht richtig gebunden zu sein aber dies ist ein anderes Thema.
Da ich dies schon erwähnt habe sei zur Vollständigkeit halber gesagt, dass im nonblocking Mode der Socketerror 10035 wohl zur Tagesordnung gehört und die Komponente TTcpClient nach der Gerüchteküche nach, nicht richtig im nonblocking mode funktioniert. Um für den blocking mode Betrieb einen Thread zu erstellen würde jede Menge umschreiberei bedeuten. Ich habe einfach das alte TClientSocket zur Laufzeit erzeugt, alle Events zugewiesen und siehe da, alles läuft wieder wunderbar.
Vielen Dank Braunstein! Stimmt, mit dem exakten Namen einer Klasse siehts wirklich schwer nach Konstruktor aus
-
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.