Wenn ich Folgendes unter Windows zum Laufen bringen möchte, was ist das richtige Gebietsschema und wie erkenne ich, dass es tatsächlich vorhanden ist: Funktioniert dieser Code universell oder ist es nur mein System?
Was ist das Windows-Äquivalent für das Gebietsschema en_US.UTF-8?
Simon Toth
Obwohl es keine gute Unterstützung für benannte Gebietsschemas gibt, enthält Visual Studio 2010 die von C++11 erforderlichen UTF-8-Konvertierungsfacetten: std::codecvt_utf8
für UCS2 und std::codecvt_utf8_utf16
für UTF-16:
#include <fstream>
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
void prepare_file()
{
// UTF-8 data
char utf8[] = {'\x7a', // latin small letter 'z' U+007a
'\xe6','\xb0','\xb4', // CJK ideograph "water" U+6c34
'\xf0','\x9d','\x84','\x8b'}; // musical sign segno U+1d10b
std::ofstream fout("text.txt");
fout.write(utf8, sizeof utf8);
}
void test_file_utf16()
{
std::wifstream fin("text.txt");
fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf8_utf16<wchar_t>));
std::cout << "Read from file using UTF-8/UTF-16 codecvt\n";
for(wchar_t c; fin >> c; )
std::cout << std::hex << std::showbase << c << '\n';
}
void test_file_ucs2()
{
std::wifstream fin("text.txt");
fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf8<wchar_t>));
std::cout << "Read from file using UTF-8/UCS2 codecvt\n";
for(wchar_t c; fin >> c; )
std::cout << std::hex << std::showbase << c << '\n';
}
int main()
{
prepare_file();
test_file_utf16();
test_file_ucs2();
}
Dies gibt auf meinem Visual Studio 2010 EE SP1 aus
Read from file using UTF-8/UTF-16 codecvt
0x7a
0x6c34
0xd834
0xdd0b
Read from file using UTF-8/UCS2 codecvt
0x7a
0x6c34
0xd10b
Press any key to continue . . .
Nemanja Trifunović
Im Grunde hast du Pech: http://www.siao2.com/2007/01/03/1392379.aspx
-
@Nemanja Trifunovic: Genau nicht der Sinn des Blogs. Für jede UTF-16-API wie MessageBoxW gibt es eine „ANSI“-Variante MessageBoxA, die die aktuelle „ANSI“-Codepage verwendet, um die 8-Bit-zu-UTF-16-Konvertierung durchzuführen. Sie können UTF-8 jedoch nicht als aktuelle „ANSI“-Codepage verwenden. Aber,
MultiByteToWideChar
verwendet nicht die aktuelle ANSI-Codepage. Sein erstes Argument ist die zu verwendende Codepage und dort UTF-8 (65001) ist erlaubt.– MSalter
2. Dezember 2010 um 16:28 Uhr
-
@MSalters: Der Punkt des Blogs ist, dass die Codepage 65001 kein ACP sein kann, was bedeutet, dass sie nicht als Gebietsschema für eine C++-Standardbibliothek verwendet werden kann. Die von mir erwähnte UTF-8 <> UTF-16-Konvertierung ist nicht der Punkt des Blogs, sondern meine Antwort auf die Frage, wie man UTF-8 unter Windows verwendet. Eine kürzere Antwort wäre: Verwenden Sie keine C++-Standardbibliothek für IO unter Windows.
– Nemanja Trifunovic
2. Dezember 2010 um 16:42 Uhr
-
@Let_Me_Be: Im Grunde läuft es darauf hinaus, dass
wchar_t
unter Windows ist speziell als 16-Bit-Typ definiert. Die C- (und C++)-Standards erfordernwchar_t
halten zu können irgendein gültiges Zeichen von alle unterstützte Kodierungen. Aber da ist auf keinen Fall alle Unicode-Zeichen in 16 Bit zu codieren – das geht einfach nicht. Daher die Windows C- und C++-Bibliotheken nicht tatsächlich Unicode jeglicher Art unterstützen. Wenn Sie Unicode unter Windows verwenden möchten, müssen Sie die C- und C++-Bibliotheken verlassen. Ja, es ist dumm, aber was haben Sie von Microsoft erwartet? 😛– Dan Formen
2. Dezember 2010 um 17:39 Uhr
-
@Let_Me_Be: Du verwechselst 16 Bit
wchar_t
und UTF-16. Sie sind nicht dasselbe. UTF-8 und UTF-16 sind zwei verschiedene Arten, alle Unicode-Codepunkte (von denen es gibt weit mehr als nur 65535). Du brauchst bei am wenigsten 24 Bit zur Darstellung aller über 1.000.000 Unicode-Codepunkte. Die “16” in UTF-16 tut es nicht bedeutet, dass alle Zeichen mit nur 16 Bit darstellbar sind (zum Beispiel erfordern einige Unicode-Zeichen 32 Bit [two 16-bit code units ] bei Codierung mit UTF-16). Aber die C++-Bibliothek erfordertwchar_t
eindeutig darstellen zu können jeden unterstützter Charakter.– Dan Formen
2. Dezember 2010 um 18:43 Uhr
-
@Let_Me_Be: Ich habe deine verknüpfte Frage gelesen, aber es scheint, dass du die richtige Antwort dort nicht verstanden hast. Einige (oder sogar alle) der Windows-APIs interpretieren darf
wchar_t
Zeichenfolgen als UTF-16-codierte Daten, aber die C- und C++-Bibliotheken nicht. Wenn dies der Fall wäre, könnten Sie UTF-8 als Gebietsschema für die C- und C++-Bibliotheken verwenden. Aber das kannst du nicht. Und das ist die Antwort auf deine Frage hier 😉– Dan Formen
3. Dezember 2010 um 14:52 Uhr
phuclv
In der Vergangenheit war UTF-8 (und einige andere Codepages) nicht als Systemgebietsschema erlaubt, weil
Microsoft sagte, dass ein UTF-8-Gebietsschema einige Funktionen beschädigen könnte, da sie geschrieben wurden, um anzunehmen, dass Multibyte-Codierungen nicht mehr als 2 Bytes pro Zeichen verwenden, sodass Codepages mit mehr Bytes wie UTF-8 (und auch GB 18030, cp54936) dies nicht könnten als Gebietsschema festgelegt werden.
https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows#UTF-8
Allerdings hat Microsoft nach und nach eingeführt UTF-8-Locale-Unterstützung und fing an, die ANSI-APIs zu empfehlen (-A
) wieder anstelle des Unicodes (-W
)-Versionen wie zuvor
Bis vor kurzem hat Windows “Unicode” betont
-W
Varianten vorbei-A
APIs. Neuere Versionen haben jedoch die ANSI-Codepage und verwendet-A
APIs als Mittel zur Einführung von UTF-8-Unterstützung in Apps. Wenn die ANSI-Codepage für UTF-8 konfiguriert ist,-A
APIs arbeiten in UTF-8. Dieses Modell hat den Vorteil, dass vorhandener Code unterstützt wird, mit dem erstellt wurde-A
APIs ohne Codeänderungen.-A vs. -W-APIs
Zuerst fügten sie a hinzu “Beta: Unicode UTF-8 für weltweite Sprachunterstützung verwenden” Checkbox seit Windows 10 Insider Build 17035 zum Setzen der Gebietsschema-Codepage auf UTF-8
Um dieses Dialogfeld zu öffnen, öffnen Sie das Startmenü, geben Sie “Region” ein und wählen Sie es aus Regionseinstellungen > Zusätzliche Datums-, Uhrzeit- und regionale Einstellungen > Datums-, Uhrzeit- oder Zahlenformate ändern > Verwaltung
Nach der Aktivierung können Sie anrufen setlocal
wie normal:
Ab Windows 10 Build 17134 (April 2018 Update) unterstützt die Universal C Runtime die Verwendung einer UTF-8-Codepage. Dies bedeutet, dass
char
Zeichenfolgen, die an C-Laufzeitfunktionen übergeben werden, erwarten Zeichenfolgen in der UTF-8-Codierung. Um den UTF-8-Modus zu aktivieren, verwenden Sie „UTF-8“ als Codepage, wenn Sie verwendensetlocale
. Zum Beispiel,setlocale(LC_ALL, ".utf8")
verwendet die aktuelle Standard-Windows-ANSI-Codepage (ACP) für das Gebietsschema und UTF-8 für die Codepage.
Sie können dies auch in älteren Windows-Versionen verwenden
Um diese Funktion auf einem Betriebssystem vor Windows 10 zu verwenden, wie z. B. Windows 7, müssen Sie verwenden App-lokale Bereitstellung oder statisch mit Version 17134 des Windows SDK oder höher verknüpfen. Für Windows 10-Betriebssysteme vor 17134 wird nur statische Verknüpfung unterstützt.
Später im Jahr 2019 fügten sie die Möglichkeit für Programme hinzu, das UTF-8-Gebietsschema zu verwenden, ohne auch nur das UTF-8-Beta-Flag oben zu setzen. Du kannst den … benutzen /execution-charset:utf-8
oder /utf-8
Optionen beim Kompilieren mit MSVC oder legen Sie die ActiveCodePage-Eigenschaft in appxmanifest fest
-
Eine schöne Zusammenfassung der neuen Funktion! Es ist erstaunlich, dass sie so lange gebraucht haben, um zu sagen: „Lasst uns einfach utf-8 in den C-Saiten verwenden“. Die
/utf-8
Die Option scheint jedoch nichts mit dem Kontrollkästchen zu tun zu haben. Es legt die Ausführungs- und Quellzeichensätze der Binärdatei fest, aber ich könnte mich irren.– Vehsakul
12. September 2020 um 23:47 Uhr
Pro MSDN, würde es “english_us.65001” heißen. Aber Codepage 65001 ist unter Windows etwas flockig.