c++, cout und UTF-8
Hoffentlich eine einfache Frage: cout
scheint zu sterben, wenn der Umgang mit Zeichenfolgen, die am Ende mit einem multibyte-UTF-8 char, mache ich etwas falsch? Dies ist mit GCC (Mingw) auf Win7 x64.
**Edit-Sorry, wenn ich war nicht klar genug, ich bin nicht besorgt über die fehlende Glyphen oder wie die bytes interpretiert werden, sondern lediglich, dass Sie nicht zeigen, an alle die direkt nach dem aufrufen cout << s4
(fehlende BAR). Weitere cout
s nach der ersten Anzeige überhaupt keinen text!
#include <cstdio>
#include <iostream>
#include <string>
int main() {
std::string s1("abc");
std::string s2("…"); //… = 0xE2 80 A6
std::string s3("…abc");
std::string s4("abc…");
//In C
fwrite(s1.c_str(), s1.size(), 1, stdout);
printf(" FOO ");
fwrite(s2.c_str(), s2.size(), 1, stdout);
printf(" BAR ");
fwrite(s3.c_str(), s3.size(), 1, stdout);
printf(" FOO ");
fwrite(s4.c_str(), s4.size(), 1, stdout);
printf(" BAR\n\n");
//C++
std::cout << s1 << " FOO " << s2 << " BAR " << s3 << " FOO " << s4 << " BAR ";
}
//results:
//abc FOO ��� BAR ���abc FOO abc… BAR
//abc FOO ��� BAR ���abc FOO abc…
- Wo sind Sie mit Ihrem Programm? Die Windows-Eingabeaufforderung wirklich nicht, wie Unicode-viel, also, während Sie Ihr Programm schreiben, einfach gut, die Konsole nicht weiß, was mit ihm zu tun.
- Die Windows-Konsole-subsystem nicht haben echte Probleme.
WriteConsoleW
funktioniert auch Recht gut, bei korrekten Schriftarten. Windows mag es nicht, UTF-8, obwohl, was bedeutet, dassWriteConsoleA
wird ersticken hier. - Funktioniert bei mir unter Ubuntu/gnome-terminal/GCC. Ich vermute immer dieses Recht erfordert, dass sowohl C++ Richtigkeit und Einnahme von Plattform-Spezifika zu berücksichtigen.
- Oh stimmt, ich sollte haben mehr spezifischen.
- Leiten Sie die Ausgabe in eine Datei und öffnen Sie diese Datei in notepad. Was passiert?
- Aufruf SetConsoleCP(65001) ist erforderlich, um die Schalter der Konsole auf utf8. Das finden einer schriftart mit fester Zeichenbreite, die fähig ist, der die Anzeige von Unicode-Symbole wird das schwierige problem.
- Passant: Lucinda Console Truetype sollte den trick tun. Siehe support.microsoft.com/kb/99795
- es nicht, es hat nur sehr wenige Glyphen. Check it out mit charmap.exe
- Das nächste problem, das Sie kämpfen, ist, dass der CRT-code nicht handhaben ein Unicode-Codepage korrekt. Behoben in der nächsten version von VS, fallback auf WriteConsole(). Wenn Sie den Eindruck bekommen, Sie versuchen, etwas zu tun, die nicht gut unterstützt, dann hast du Recht.
- Nicht in der Lage zu handhaben UTF-8 ist nicht ein echtes Problem??? Es ist ein Todesstoß.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist wirklich keine überraschung. Es sei denn, Ihr terminal auf UTF-8 Codierung, Woher weiß er, dass
s2
soll nicht sein "(Latin small letter a with circumflex)(Euro-Zeichen)(Pipe)",Sie meinte, daß Ihr terminal ISO-8859-1 nach http://www.ascii-code.com/
Durch die Art und Weise, cout ist nicht "sterben", wie es eindeutig weiterhin zu produzieren, die Ausgabe nach Ihren test-string.
std::cout
nur Echos, einen Datenstrom von bytes auf die Außenwelt. Wie Sie interpretiert werden, wird zwischen Ihnen und dem Programm, das letztendlich Lesen, diese bytes.chcp 65001
Wenn Sie möchten, dass Ihr Programm verwenden Sie Ihre aktuelle locale, rufen Sie
setlocale(LC_ALL, "")
als das erste, was in Ihrem Programm. Ansonsten wird das Programm die locale istC
und was wird es tun, um nicht-ASCII-Zeichen ist nicht erkennbar, von uns bloßen Menschen.setlocale(LC_ALL, "")
und tunchcp 65001
war der trick für Unicode in der KonsoleDie Windows-Konsole ist nicht in der Lage, nicht-lokale-codepage-Zeichen standardmäßig.
Müssen Sie sicherstellen, dass Sie einen Unicode-fähigen Zeichensatz in der Konsole-Fenster, und dass der Zeichensatz ist auf UTF-8 eingestellt durch einen Aufruf
chcp
. Dies ist kein garantierter Erfolg aber.Beachten Sie, dass `wcout ändert sich nichts, wenn die Konsole nicht zeigen, die ausgefallene Charaktere, weil seine Schrift ist Murks.
Auf allen modernen Linux-Distributionen, die Konsole auf UTF-8 eingestellt und das sollte funktionieren out of the box.
Wie andere haben darauf hingewiesen,
std::cout
ist agnostisch, was, zumindest in"C"
locale (der Standard). Auf der anderen Seite, können Sie Ihre Konsole-Fenster muss eingestellt werden, Anzeige UTF-8-Codepage 65001. Versuchen Sie es aufrufenchcp 65001
vor der Ausführung Ihres Programms. (Dies hat für mich gearbeitet in der Vergangenheit.)