wstring vs string - kurze Nachfrage
-
Eisflamme schrieb:
Was ich davon hätte? Ich kann das Ding wie einen ganz normalen string nutzen. Bisher habe ich keinen Vorschlag gesehen, der einfacher wäre.
std::basic_string<wchar32_t>
bzw.std::u32string
?
-
...
Und was ist daran einfacher?
-
Eisflamme schrieb:
Und was ist daran einfacher? -.-
Es ist genauso einfach, aber dafür korrekt.
-
stuxn schrieb:
Ich moecht mich hier gleich mal anschießen und fragen wie man richtig von (windows) wchar_t zu utf-8 konvertiert.
Unter Windows kann man (auch) die WinAPI dafür nehmen:
#include <windows.h> #include <iostream> #include <string> using namespace std; wstring toWide(string in, UINT from) { int len = MultiByteToWideChar(from, 0, in.c_str(), -1, 0, 0); if(!len) cout << "Fehler toWide?!\n"; WCHAR *res = new WCHAR[len]; int result = MultiByteToWideChar(from, 0, in.c_str(), -1, res, len); if(result != len) cout << "Fehler toWide?!\n"; wstring s(res); delete[] res; return s; } string toMultiByte(wstring in, UINT to) { const int len = WideCharToMultiByte(to, 0, in.c_str(), -1, 0, 0, 0, 0); if(!len) cout << "Fehler toMBCS 1?!\n"; char *res = new char[len]; int result = WideCharToMultiByte(to, 0, in.c_str(), -1, res, len, 0, 0); if(result != len) cout << "Fehler toMBCS2?!\n"; string s(res); delete[] res; return s; } string AnsiToUTF8(const string &in) { wstring tmp = toWide(in, CP_ACP); string res = toMultiByte(tmp, CP_UTF8); return res; } string UTF8ToAnsi(const string &in) { wstring tmp = toWide(in, CP_UTF8); string res = toMultiByte(tmp, CP_ACP); return res; } int main() { string utf8 = AnsiToUTF8("äöÜ"); string ansi = UTF8ToAnsi(utf8); cout << utf8; cerr << ansi; }
Dein Codeschnipsel sieht weitaus einfacher aus, aber ob er korrekt ist, weiß ich nicht.
-
Eisflamme schrieb:
Lesen der Qt Dokumentation bedeutet auch, den "siehe auch" Links zu folgen!
Genau, ich lese die gesamte QT Dokumentation durch und folge allen "siehe auch"-Links. Sorry, aber wenn Du weißt, was ich Deiner Meinung nach nachschlagen soll, dann sag es doch einfach statt einen minder sinnvollen Hinweis wie "Les die QT Dokumentation" zu geben... nett gemeint, danke, aber war für mich nicht hilfreich.
War nur nicht hilfreich, weil du nicht fähig/willens(/...?) bist Dokumentation zu lesen.
Ich meine hallo, wenn da steht "alles was QTextCodec::codecForCStrings() nicht konvertieren kann" (sinngemäss), dann ist logischerweise die nächste Frage "na was kann denn QTextCodec::codecForCStrings()?".
Dann guckst du nach, siehst dass man da was umstellen kann und *schwupps* hättest du zum ersten mal nicht-trivialen Gebrauch einer Doku gemacht.Natürlich kannst du stattdessen auch alle Leute anpflaumen die dir nahelegen mal in der Doku nachzusehen. Dauert länger und du lernst nix dabei, aber naja ... ist deine Entscheidung.
-
hättest du zum ersten mal nicht-trivialen Gebrauch einer Doku gemacht.
Na ja, wenn Du mir einfach Dinge unterstellst, kann ich Deine Kritik an meiner Kritik einer Antwort (was hier im Forum aber sowieso - sinnloserweise - kategorisch ein No-Go ist) nicht ernst nehmen, auch wenn da wahre Punkte dran sind.
Zum Thema:
Was ist anstd::basic_string<wchar32_t> bzw. std::u32string
korrekter? wstring ist meinem Verständnis nach die UTF-16-Enkodierung für Unicode, die valide und keineswegs inkorrekt ist. wchar32_t oder u32string zu verwenden nutzt immer noch nicht UTF-8 aus. Solange UTF-16 meine Sonderzeichen beinhaltet, erscheint mir das nach wie vor als einfachste (und gleichzeitig speicherschonenste) Variante meine Problemstellung zu lösen. Die optimale Lösung scheint es ja tatsächlich nicht zu geben.
Auch ein Projekt, auf das in dem Artikel ( http://www.joelonsoftware.com/articles/Unicode.html ) verwiesen wird, fällt die Entscheidung auf UTF-16. Bestätigt doch, dass das valide ist, oder?
-
Eisflamme schrieb:
wstring ist meinem Verständnis nach die UTF-16-Enkodierung für Unicode, ...
Nein (s. mein erstes Posting in diesem Thread) - man kann wstring so 'missbrauchen', wenn man es darauf anlegt, aber so ist std::wstring nicht gemeint.
.. vielleicht melde ich mich später noch mal.
Gruß
Werner
-
Echt? Dann hat mich der Artikel irregeführt:
For the latest version of CityDesk, the web site management software published by my company, we decided to do everything internally in UCS-2 (two byte) Unicode, which is what Visual Basic, COM, and Windows NT/2000/XP use as their native string type. In C++ code we just declare strings as wchar_t ("wide char") instead of char and use the wcs functions instead of the str functions (for example wcscat and wcslen instead of strcat and strlen). To create a literal UCS-2 string in C code you just put an L before it as so: L"Hello".
Hier wird das Problem nicht angesprochen. Dann muss ich wohl noch mehr Artikel lesen... Deinen Post auf S.1 habe ich auch nochmal gelesen. Das Problem ist, dass die jeweilige locale nicht 16 Bit enthalten muss (sondern weniger kann) oder wie?
-
Dieses UCS-2 ist mittlerweile veraltet. Der Artikel von Joel hat ein paar subtile Fehler, lies lieber http://www.utf8everywhere.org/.
Werner Salomons Aussage ist, dass ein String kein Encoding enthalten sollte, sondern direkt die Codepoints speichern soll. Das ist so richtig, heisst aber in letzter Instanz Unicode <=> u32string und kein Unicode (z.B. das von Werner empfohlene Big5) <=> u16string. Mit wstring fangen die Probleme schon damit an, dass wchar_t signed sein kann und nicht klar ist, wie viel Bits mindestens aufgenommen werden können.
-
Hi,
okay, habe "utf8everywhere" jetzt auch komplett gelesen.
Der Autor empfiehlt ja einfach std::string zu nutzen und anzunehmen, dass einfach jeder UTF8 verwendet. Okay. Aber splits usw. werden dann doch außerordentlich gefährlich, wie bereits angemerkt, oder? Denn wenn char hinterlegt wird, entspricht ja jedes Zeichen einem 32-Bitter. Iterieren und []-Operator sollten dann doch wohl nicht funktionieren.
Wieso löst u32string das Problem nicht? utf8everywhere sagt ja, dass die C++-Unicode-Implementierung Murks ist (also wohl auch u32string) und der Artikel wurde 2013 zuletzt überarbeitet.
-
std::string ist fuer den Umgang mit Unicode/UTF-8 ungeeignet, du wirst wohl auf eine Library zurueckgreifen muessen.
Aber es gibt Hoffnung. Immerhin hat das Kommittee erkannt, dass ein Stringtyp, der Encoding nicht beruecksichtigt, ziemlich nutzlos ist, und es gibt sogar schon einen Proposal, der hoffentlich bis C++14 akzeptiert sein wird. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3572.html
-
Eisflamme schrieb:
Hi,
okay, habe "utf8everywhere" jetzt auch komplett gelesen.
Der Autor empfiehlt ja einfach std::string zu nutzen und anzunehmen, dass einfach jeder UTF8 verwendet. Okay. Aber splits usw. werden dann doch außerordentlich gefährlich, wie bereits angemerkt, oder? Denn wenn char hinterlegt wird, entspricht ja jedes Zeichen einem 32-Bitter. Iterieren und []-Operator sollten dann doch wohl nicht funktionieren.
Wieso löst u32string das Problem nicht? utf8everywhere sagt ja, dass die C++-Unicode-Implementierung Murks ist (also wohl auch u32string) und der Artikel wurde 2013 zuletzt überarbeitet.
Kannst du ein konkretes Problem nennen das du mit UTF-8 hast und nicht nur theoretische Probleme, die unter diesen und jenen Umständen auftreten können?
-
Mein Ausgangsproblem war ja, dass ich EUR- und Pfundzeichen nicht habe. Die Lösung wstring zu verwenden wurde mir aber jetzt mehr als madig geredet (siehe letzten Seiten des Threads). Die Begründungen gegen wstring sind auf utf8everywhere ja erläutert.
-
Wenn ich dich richtig verstanden habe, hast Du lediglich ASCII und einige gängige Währungssymbole.
Wenn Du das garantieren kannst, hast Du mit UTF-16 alles was Du brauchst. Alles befindet sich in der BMP und es können keine Surrogate in deinem Text auftauchen, d.h. jedes Zeichen ist in genau einem 16-Bit-Wert kodiert. (Entspricht dann UCS-2)
-
Okay. Aber da wstring das ja nicht anbietet, wie realisiere ich das dann gescheit?
-
Was bietet wstring nicht an?
-
UTF-16 wie auf den vorherigen Seiten diskutiert.
-
QString gibt dir auf Anfrage einen
wstring
in UTF-16 oder UCS-4, je nach Plattform. In beiden Fällen wird unter den o.g. Voraussetzungen jedes Zeichen in einemwchar_t
abgebildet.QString::toStdWString()
Wenn Du willst kannst Du auch ein Array vonunsigned short
bekommen.QString::utf16()
-
Eisflamme schrieb:
hättest du zum ersten mal nicht-trivialen Gebrauch einer Doku gemacht.
Na ja, wenn Du mir einfach Dinge unterstellst, kann ich Deine Kritik an meiner Kritik einer Antwort (was hier im Forum aber sowieso - sinnloserweise - kategorisch ein No-Go ist) nicht ernst nehmen, auch wenn da wahre Punkte dran sind.
Denk mal drüber nach was du da
schreibstgeschrieben hast. Macht nämlich keinen Sinn.Und lies dir nochmal diese Aussage von dir durch:
Genau, ich lese die gesamte QT Dokumentation durch und folge allen "siehe auch"-Links.
Niemand hat von dir verlangt allen "siehe auch"-Links zu folgen.
-
Niemand hat von dir verlangt allen "siehe auch"-Links zu folgen.
Damit wollte ich sagen: Präzisier den Hinweis bitte, sonst kannst Du ihn Dir auch sparen. "Lies die Doku" ist ein so allgemeiner Ratschlag, dass man ihn sich einfach sparen kann. Und ja, natürlich hätte ich toStdString() noch genauer durchlesen können, wenn ich mich besonders für QT interessiert hätte - im Fokus steht aber (siehe Threadtitel) die Variante ohne QT, dafür mit Standard.
Macht nämlich keinen Sinn.
Du unterstellst mir indirekt, ich hätte vorher noch nie nicht-trivialen Gebrauch von einer Doku gemacht. Oder bestreitest Du das?