Ich habe einige Artikel über Unicode Lesen und erkannte ich bin verwirrt noch übrig, was dagegen zu tun genau.C++ String noch wörtlichen verwirrend
als C++ Programmierer auf Windows-Plattform, die ich gegeben Disziplinen waren von jedem Lehrer meist gleich: immer Unicode-Zeichensatz verwenden; templatisieren Sie es oder verwenden Sie TCHAR wenn möglich; bevorzuge wchar_t, std :: wstring über char, std :: string.
#include <tchar.h>
#include <string>
typedef std::basic_string<TCHAR> tstring;
// ...
static const char* const s_hello = "핼로"; // bad
static const wchar_t* const s_wchar_hello = L"핼로" // better
static LPCTSTR s_tchar_hello = TEXT("핼로") // even better
static const tstring s_tstring_hello(TEXT("핼로")); // best
Irgendwie verwirrt ich, und ich führen mich zu glauben, dass, wenn ich „etwas“ sagen, dass es im ASCII-Format bedeutet, und wenn ich L „etwas“ sagen ist es Unicode. Dann lese ich das:
Typ wchar_t ist ein unterschiedlicher Typ, dessen Werte unterschiedliche Codes für alle Mitglieder des größten erweiterten Zeichensatzes, der unter den unterstützten Gebietsschemata (22.3.1) angegeben ist, darstellen können. Typ wchar_t muss die gleiche Größe, Signedness und Alignment-Anforderungen (3.11) wie einer der anderen ganzzahligen Typen haben, der so genannte zugrunde liegende Typ. Typen char16_t und char32_t verschiedene Arten mit der gleichen Größe, Signedness und Ausrichtung wie uint_least16_t und uint_least32_t bezeichnen jeweils, an, um die zugrunde liegenden Typen genannt.
So what? Wenn mein Gebietsschema von der Codepage 949 aus beginnt, ist die Ausdehnung von wchar_t von 949 + 2^(sizeof (wchar_t) * 8)? Und die Art, wie es spricht, klingt wie "Es ist mir egal, ob Ihre Implementierung von C++ UTF-Kodierung verwendet oder was".
Zumindest konnte ich verstehen, dass alles davon abhängt, auf welchem Gebietsschema die Anwendung läuft. So testete ich:
#define TEST_OSTREAM_PRINT(x) \
std::cout << "----" << std::endl; \
std::cout << "cout : " << x << std::endl; \
std::wcout << "wcout : " << L##x << std::endl;
int main()
{
std::ostream& os = std::cout;
std::cout << " * Info : " << std::endl
<< " sizeof(char) : " << sizeof(char) << std::endl
<< " sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl
<< " littel endian? : " << IsLittelEndian() << std::endl;
std::cout << " - LC_ALL: " << setlocale(LC_ALL, NULL) << std::endl;
std::cout << " - LC_CTYPE: " << setlocale(LC_CTYPE, NULL) << std::endl;
TEST_OSTREAM_PRINT("핼로");
TEST_OSTREAM_PRINT("おはよう。");
TEST_OSTREAM_PRINT("你好");
TEST_OSTREAM_PRINT("resume");
TEST_OSTREAM_PRINT("résumé");
return 0;
}
Dann Ausgang war:
Info
sizeof(char) = 1
sizeof(wchar_t) = 2
LC_ALL = C
LC_CTYPE = C
----
cout : 핼로
wcout : ----
cout : おはよう。
wcout : ----
cout : ?好
wcout : ----
cout : resume
wcout : resume
----
cout : r?sum?
wcout : r?um
Ein anderer Ausgang mit koreanischen locale:
Info
sizeof(char) = 1
sizeof(wchar_t) = 2
LC_ALL = Korean_Korea.949
LC_CTYPE = Korean_Korea.949
----
cout : 핼로
wcout : 핼로
----
cout : おはよう。
wcout : おはよう。
----
cout : ?好
wcout : ----
cout : resume
wcout : resume
----
cout : r?sum?
wcout : resume
Ein anderer Ausgang:
Info
sizeof(char) = 1
sizeof(wchar_t) = 2
LC_ALL = fr-FR
LC_CTYPE = fr-FR
----
cout : CU·I
wcout : ----
cout : ªªªIªeª|¡£
wcout : ----
cout : ?u¿
wcout : ----
cout : resume
wcout : resume
----
cout : r?sum?
wcout : resume
Es stellt sich heraus, wenn ich Geben Sie nicht das richtige Gebietsschema, Anwendung kann bestimmte Zeichenbereiche nicht verarbeiten, egal, ob ich char oder wchar_t verwendet habe. Das ist nicht nur ein Problem. Visual Studio gibt Warnung:
warning C4566: character represented by universal-character-name '\u4F60' cannot be represented in the current code page (949)
Ich bin nicht sicher, ob dies beschreibt, was ich als Ausgabe oder etwas anderes bekomme.
Frage. Was wären die besten Praktiken und warum? Wie kann man eine Anwendungsplattform/Implementierung/Nation unabhängig machen? Was genau passiert mit String-Literalen auf der Quelle? Wie werden String-Werte von der Anwendung interpretiert?
Für maximale Kompatibilität: Halten Sie die Zeichen in Ihrer Quelle zu den sehr einfachen ASCII-Zeichen. Verwenden Sie die UTF8-Codierung mit Bytes, die mit \ x in Strings definiert sind. Der neue u8 "\ u1234" Kram in der neuesten Version von C++ wird dies vereinfachen, aber es wird noch nicht von Visual Studio unterstützt. Siehe auch diese Frage: http://stackoverflow.com/questions/3768363/character-sets-not-clear – JCx
'TCHAR' s sind eine gigantische Hektik. Wenn Sie nicht wirklich alte Windows-Versionen unterstützen möchten, geben Sie Windows-Strings einfach weiter. Um Kompatibilität mit anderen Dingen zu gewährleisten, können Sie Zeichenketten mit UTF-8 speichern und bei Verwendung einer Windows-API-Funktion konvertieren. – chris