Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen
-
@Th69 sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Evtl. mußt du aber mal in Informationen zur Zeichencodierung - PowerShell nachlesen.
Das habe ich mir bereits durchgelesen, aber keine der angebotenen Optionen bewirkt etwas. An sich eine Hilfeseite ohne Hilfe.
-
@tech-house sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Dein Vorschlag funktioniert leider nicht, ich habe http://www.unifoundry.com/pub/unifont/ installiert, und jetzt sind da noch mehr Fragezeichen, anstatt weniger.
Und ...
echo "╭╮╯╰"
funktioniert bei mir auch, das ändert aber nichts an der Ausgabe des Kommandozeilenprogramms.Wenn echo funktioniert zeigt es dass powershell und die eingestellte font das können.
Bist du sicher das dein Programm utf-16 ausgibt?
Entweder dein Programm gibt kein utf-16 aus oder die verwendete ausgabefunktion konvertiert die daten z.b. in die lokale codepage bevor diese die powershell erreichen.Wie sieht der code des Programms für die ausgabe aus?
-
@tech-house sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Die Commands
chcp
undchcp 65001
funktionieren zwar, aber, wie bereits gezeigt, werden nicht alle Zeichen dargestellt.Die Codepage 65001 ist eigentlich auch UTF-8, wie @firefly schon schrieb wäre es mal gut, deinen Ausgabe-Code zu sehen. Für direkte UTF-16-Ausgabe würde ich auch vermuten, dass man das über
std::wcout
machen müsste. Mitstd::cout
liegen dann nämlich noch einige Konvertierungen dazwischen, entweder von der C-Runtime und/oder dem Terminal, was dieses Thema generell immer etwas fummelig macht, wenn man es richtig hinbekommen will.In persönlich mache mit C++ immer UTF-8-Ausgabe um das zwischen Linux und Windows zu vereinheitlichen und für Windows nicht zu viel extra Code schreiben zu müssen. Das sieht dann etwa so aus:
#include <iostream> #ifdef _WIN32 #include <Windows.h> #endif auto main() -> int { #ifdef _WIN32 SetConsoleOutputCP(CP_UTF8); // Das ist de facto `chcp 65001` #endif std::cout << "╭╮╯╰" << std::endl; }
Das funktioniert zumindest bei mir so problemlos (Windows Terminal mit Powershell und "Inconsolata" als Schriftart).
Wichtig ist dabei, dass der Quellcode auch in UTF-8 ohne BOM gespeichert wurde. Das ist soweit ich weiss bei Visual Studio nicht Standard. Dort muss die Datei als "Unicode (UTF-8 without signature) - Codepage 65001" gespeichert werden.
Wenn es unbedingt UTF-16 sein soll, kann ich so auf Anhieb nicht weiterhelfen. Eigentlich sollte UTF-16 auch die Standard-Ausgabeformat für Powershell wie auch allen unter Windows, das mit "Unicode" zu tun hat sein. Da sollte man eigentlich nichts "umstellen" müssen, probiers einfach mal mit
std::wstring
,std::wcout
undL"abc"
-String-Literalen.
-
@Finnegan sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Wichtig ist dabei, dass der Quellcode auch in UTF-8 gespeichert wurde. Das ist soweit ich weiss bei Visual Studio nicht Standard. Dort muss die Datei als "Unicode (UTF-8 without signature) - Codepage 65001" gespeichert werden.
Alternativ kann man die zeichen auch in "escaped" form (\u<hexzahl>) verwenden.
z.b. "╭" ist U+256D => "\u256D"Um auf dein Beispiel zu münzen
std::cout << "╭╮╯╰" << std::endl;
würde es dann so aussehen
std::cout<<"\u256D\u256E\u256F\u2570";
Dadurch ist man unabhängig der verwendeten kodierung des source codes.
-
@firefly sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
@Finnegan sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Wichtig ist dabei, dass der Quellcode auch in UTF-8 gespeichert wurde. Das ist soweit ich weiss bei Visual Studio nicht Standard. Dort muss die Datei als "Unicode (UTF-8 without signature) - Codepage 65001" gespeichert werden.
Alternativ kann man die zeichen auch in "escaped" form (\u<hexzahl>) verwenden.
z.b. "╭" ist U+256D => "\u256D"Mit den Escape-Codes hab ich noch nicht herumgespielt, ich hatte aber mal vor einiger Zeit ein paar Kombinationen getestet mit sehr unterschiedlichen Ergebnissen:
https://www.c-plusplus.net/forum/topic/343499/utf-8-strings-und-sonderzeichen-visual-studio-2015/5
Letztendlich finde ich die Lösung, die Datei als UTF-8 zu speichern und die Konsole auf
CP_UTF8
zu setzen die beste, weil der Code dadurch am einfachsten wird. Keine String-Präfixe, keine Escapes. Einfach nur hinschreiben, was man ausgeben will - so wie es IMHO sein sollte: Unicode als "Normalfall", nicht als "Sonderfall". Dafür nehm ich dann gern in Kauf auf die Datei-Codierung achten zu müssen .
-
@Finnegan Jo die Verwendung von utf-8 für text files sollte man generell vorziehen.
Nur macht das halt Visual Studio von haus aus leider nicht dass es überhaupt eine unicode codierung nutzt für text files sonder standardmäßig die lokale codepage des systems dafür nutzt
-
@tech-house sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Wie kann ich denn einen Unicode-Zeichensatz nachinstallieren, der nahezu alle UTF-16-Zeichen unterstützt? Am besten monospace.
Die nerdfonts dürften deine Wünsche abdecken.
-
@firefly sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
@Finnegan Jo die Verwendung von utf-8 für text files sollte man generell vorziehen.
Nur macht das halt Visual Studio von haus aus leider nicht dass es überhaupt eine unicode codierung nutzt für text files sonder standardmäßig die lokale codepage des systems dafür nutztIch behaupte mal solche Dinge sind mit einer der Hauptgründe, weshalb wir uns auch 2023 noch mit so einem archaischen Scheiss (sorry!) herumschlagen müssen
-
@Finnegan Seit VS2017 kann man das was mit der .editorconfig machen.
https://stackoverflow.com/questions/41335199/how-to-config-visual-studio-to-use-utf-8-as-the-default-encoding-for-all-project/65945041#65945041Wobei ich was gelesen habe, dass es mittlerweile bei default utf-8 sein soll. Da ich aktuell kein Visual Studio zu hand habe kann ich das nicht nachprüfen.
Aber da die non Unicode api von windows UTF-8 bei default nicht verwendet sondern ANSI codepage hilft es nicht wenn der code in UTF-8 gespeichert wird.
Da hilft es nur entweder die wide char variante der api zu nutzen oder via SetConsoleOutputCP(CP_UTF8);
Die consolen ausgabe auf UTF-8 umzustellen statt default ANSI
-
@firefly sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Aber da die non Unicode api von windows UTF-8 bei default nicht verwendet sondern ANSI codepage hilft es nicht wenn der code in UTF-8 gespeichert wird.
Das ist in der Tat ein Problem. Für ein reines Windows-Programm, dass hauptsächlich Funktionen der Windows-API verwendet, würde ich daher auch eher UTF-16 empfehlen. Bei den Programmen, an denen ich meist arbeite, ist das aber so gut wie nie der Fall, daher wird dort eben an der Schnittstelle zum OS entsprechend zu UTF-16 konvertiert. Das ist die "Windows wird auch unterstützt"-Perspektive, die sicher nicht jeder hat
-
@firefly sagte in Windows 11 Terminal/PowerShell auf UTF-16 Unicode umstellen:
Wie sieht der code des Programms für die ausgabe aus?
Hier ist der Code der Java-Library:
In der Java-Anwendung rufe ich:
System.out.println(ASCIIGraph.fromSeries(...).plot());
auf, wobei...
eindouble[]
ist. Aus der Java-Anwendung generiere ich eine runnable jar.Ich bin erst heute Abend wieder da... bis später
-
Tja da haben wir das problem. System.out verwendet/öffnet stdout (standard out) mit einer "default" encoding, welche wohl unter windows dann die verwendung von einer codepage entspricht.
Und nicht einer unicode kodierung.Laut https://stackoverflow.com/questions/20386335/printing-out-unicode-from-java-code-issue-in-windows-console
Soll dass hier funktionierenpublic static PrintWriter stdout = new PrintWriter( new OutputStreamWriter(System.out, StandardCharsets.UTF_8), true);
und dann
stdout.println
verwenden statt
System.out.println
Wobei laut dem stackoverflow thread das scheinbar nicht immer funktioniert.
Daher solltest du das vorher testen ob unicode auch ausgegeben wird
z.b. mit
stdout.println("\u256D");
Sollte dann "╭" ausgeben.Falls das nicht funktioniert hilft eventuell der hier beschriebene workaround damit powershell utf-8 verwendet für input/output statt OEM codepage:
-
@firefly Danke, aber es geht leider (noch) nicht... Mit
private static final PrintWriter stdout = new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8), true);
kommt leider Gemüse raus:
614,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò« 613,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò» Ôò░ÔöÇÔò« 612,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò» Ôò░ÔöÇÔöÇÔöÇÔò« 611,00 Ôöñ Ôò¡Ôò» Ôò░ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò« 610,00 Ôöñ Ôöé Ôò░ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇ 609,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔò» 608,00 Ôöñ Ôò¡ÔöÇÔöÇÔò» 607,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔò» 606,00 Ôöñ Ôò¡ÔöÇÔò«Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò» 605,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò» Ôò░Ôò» 604,00 Ôöñ Ôò¡ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔò» 603,00 ÔöñÔò¡Ôò» 602,00 Ôö╝Ôò»
Mit einem der anderen Charsets:
Charset Description US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set ISO-8859-1 ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1 UTF-8 Eight-bit UCS Transformation Format UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark
kommt leider auch nur Gemüse raus...
Aber immerhin: Die Ausgabe ist nun eine andere, nur anscheinen nicht UTF16 ...
-
Ich dachte, es läge vielleicht an der JVM, aber das hat leider auch nicht funktioniert:
https://stackoverflow.com/questions/44208347/unable-to-set-correct-encoding-in-powershellEin Versuch mit dieser neuen Methode hat auch nicht geklappt:
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/PrintStream.html#write(byte[])Es ist seltsam, dass es in der IntelliJ Konsole funktioniert (IJ hatte ich auf UTF8 umgestellt), in der PowerShell hingegen nicht, und man scheinbar daran auch nichts ändern kann, außer vielleicht die betreffenden Zeichen auszutauschen.^^
-
Tja wenn man nicht lesen kann...
Für die Person, welche das hier irgendwann lesen sollte.
Eine reine Einstellung in java ist so nicht möglich.
Man muss die Powershell selbst umstellen, dass es utf-8 nutzt für die ausgabe.
Denn wenn die powershell via startmenu eintrag gestartet wird, so wird die selbe codepage genutzt, welche auch von der cmd.exe genutzt wird.Dafür kann der workaround in dem github link verwendet werden.
[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
Dadurch wird auch die unicode zeichen, welche via System.out.println ausgegeben werden korrekt dargestellt.
Wobei ich das jetzt nur mit powershell 5.1 (welches bei Windows 10 dabei ist) getestet habe.