Gibt es eine tragbare wchar_t in C++? Unter Windows sind es 2 Bytes. Auf alles andere sind 4 Bytes. Ich möchte wstring in meiner Anwendung verwenden, aber das wird Probleme verursachen, wenn ich mich entscheide, um es zu portieren.Portable wchar_t in C++
Antwort
Wenn Sie mit der internen Verwendung des Programms zu tun haben, machen Sie sich keine Sorgen darüber; a wchar_t in Klasse A ist das gleiche wie in Klasse B.
Wenn Sie planen, Daten zwischen Windows und Linux/MacOSX-Versionen zu übertragen, haben Sie mehr als wchar_t zu kümmern, und Sie müssen sich kümmern mit Mitteln, um alle Details zu behandeln.
Sie könnten einen Typ definieren, den Sie überall mit vier Byte definieren, und Ihre eigenen Strings usw. implementieren (da die meisten Textverarbeitungen in C++ Vorlagen sind), aber ich weiß nicht, wie gut das funktionieren würde für Ihre Bedürfnisse.
So etwas wie typedef int my_char; typedef std::basic_string<my_char> my_string;
Sie würden char_traits dafür benötigen, und Sie können 'st spezialisieren :: char_traits
Sie können auch wchar_t/wstring intern verwenden. Extern verwenden Sie UTF-8, um das Endianness-Chaos zu umgehen. Konvertieren Sie bei E/A zwischen wchar_t und UTF-8 mithilfe von Template-Funktionen, die auf sizeof (wchar_t) spezialisiert sind. – MSalters
-1 Die Verwendung von my_char ist eine schlechte Idee. Sie können eine Zeichenfolge zum Streamen schreiben, mit der Sie nichts anfangen können – Artyom
Was meinen Sie mit "portable wchar_t"? Es gibt einen uint16_t
Typ, der überall 16 Bit breit ist, was oft verfügbar ist. Aber das macht natürlich noch keinen Strich. Ein String muss wissen, wie er codiert wird, um Funktionen wie length()
, substring()
usw. zu verstehen (also schneidet er keine Zeichen in der Mitte eines Codepunkts, wenn utf8 oder 16 verwendet wird). Es gibt einige Unicode-kompatible String-Klassen, die ich verwenden kann. Alle können kostenlos in kommerziellen Programmen verwendet werden (die Qt One wird in einigen Monaten kostenlos mit kommerziellen Programmen kompatibel sein, wenn Qt 4.5 veröffentlicht wird).
ustring
aus dem gtkmm
Projekt. Wenn Sie mit gtkmm programmieren oder glibmm verwenden, sollte das die erste Wahl sein, intern wird utf-8
verwendet. Qt
hat auch eine String-Klasse namens QString. Es ist in utf-16
codiert. ICU
ist ein anderes Projekt, das portable Unicode-String-Klassen erstellt und eine UnicodeString
Klasse hat, die intern in utf-16 kodiert zu sein scheint, wie Qt. Hab das aber noch nicht benutzt.
Eigentlich haben length(), substring() und Co. keine Ahnung von der Kodierung, sie schauen sich nur die Größe der Kodierungseinheit an und arbeiten daran. –
@Mihai, sicher, das ist der Fall der Funktion std :: string. Aber das ist der Grund, warum es nicht für utf8 usw. verwendet werden kann. –
@Johannes Schaub: aber die Antwort lautet: "Eine Zeichenfolge muss wissen, dass ihre Codierung Funktionen wie length(), substring() sinnvoll macht" Also nein, es muss nicht wissen. Sie können in Codeeinheiten arbeiten, ohne die Kodierung zu kennen, alles was Sie brauchen ist die Größe der Codeeinheit. –
Die vorgeschlagene C++ 0x-Standard wird char16_t
und char32_t
Typen haben. Bis dahin müssen Sie auf Ganzzahlen für den Nicht-wchar_t
-Zeichentyp zurückgreifen.
#if defined(__STDC_ISO_10646__)
#define WCHAR_IS_UTF32
#elif defined(_WIN32) || defined(_WIN64)
#define WCHAR_IS_UTF16
#endif
#if defined(__STDC_UTF_16__)
typedef _Char16_t CHAR16;
#elif defined(WCHAR_IS_UTF16)
typedef wchar_t CHAR16;
#else
typedef uint16_t CHAR16;
#endif
#if defined(__STDC_UTF_32__)
typedef _Char32_t CHAR32;
#elif defined(WCHAR_IS_UTF32)
typedef wchar_t CHAR32;
#else
typedef uint32_t CHAR32;
#endif
Nach der Norm, müssen Sie char_traits
für die Integer-Typen spezialisieren. Aber auf Visual Studio 2005 bin ich mit std::basic_string<CHAR32>
ohne besondere Behandlung davongekommen.
Ich plane, eine SQLite-Datenbank zu verwenden.
Dann müssen Sie UTF-16, nicht wchar_t
verwenden.
Die SQLite-API hat auch eine UTF-8-Version. Vielleicht möchten Sie das verwenden, anstatt mit den wchar_t
Unterschieden umzugehen.
Mein Vorschlag. Verwenden Sie UTF-8 und std :: string. Breite Saiten würden dir nicht zu viel Mehrwert bringen. Da Sie Breitzeichen ohnehin nicht als Buchstaben interpretieren können, wie einige Zeichen aus mehreren Unicode-Codepunkten.
Verwenden Sie also überall UTF-8 und verwenden Sie gute Bibliothek, um mit natürlichen Sprachen umzugehen. Wie zum Beispiel Boost.Locale.
Schlechte Idee: Definieren Sie etwas wie typedef uint32_t mychar;
ist schlecht. Da Sie Iostream damit nicht verwenden können, können Sie beispielsweise keinen streamstream in diesem Zeichen erstellen, da Sie nicht in der Lage wären, darin zu schreiben.
Zum Beispiel würde dies nicht funktionieren:
std::basic_ostringstream<unsigned> s;
ss << 10;
Möchten Sie einen String nicht erstellen.
Möchten Sie Daten zwischen Windows und anderen Betriebssysteminstallationen (z. B. Dateien, Sockets) freigeben? Wenn nicht, dann denke ich, dass Sie sich nicht um dieses Problem kümmern müssen (solange Sie sizeof anstelle von 2 oder 4 verwenden). –
Ich plane, eine SQLite-Datenbank zu verwenden. –
http://stackoverflow.com/questions/421530/is-endian-conversion-required-for-wchart-data#421603 –