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"

    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 nutzt

    Ich 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#65945041

    Wobei 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 😁


  • Banned

    @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:

    https://github.com/MitchTalmadge/ASCII-Data/blob/master/src/main/java/com/mitchtalmadge/asciidata/graph/ASCIIGraph.java#L141

    In der Java-Anwendung rufe ich: System.out.println(ASCIIGraph.fromSeries(...).plot()); auf, wobei ... ein double[] 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 funktionieren

    public 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:

    https://github.com/PowerShell/PowerShell/issues/7233


  • Banned

    @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 ...


  • Banned

    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-powershell

    Ein 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.


Log in to reply