2014-12-23 10 views
10

Char ist der Typ für Unicode-Zeichen in Haskell, und String ist einfach [Char] (d. H. Eine Liste von Char Elemente). Hier finden Sie einige einfache Code:Laufzeitausnahme beim Drucken eines Unicode-Zeichens

main = putStrLn "©" -- Unicode string 

Dieser Code kompiliert in Ordnung, aber ich bekomme die Runtime-Ausnahme, wenn ich es laufen in der PowerShel.exe oder cmd.exe:

App. exe:: commitBuffer: ungültiges Argument (ungültiges Zeichen)

Warum passiert das? Seltsam genug, wenn ich das gleiche in C# zu tun, erhalte ich keine Ausnahme:

Console.WriteLine("©"); 

In .NET Zeichen sind zu Unicode. PowerShell oder cmd druckt c statt ©, aber zumindest bekomme ich keine Ausnahme. Wie kann ich meine Haskell-Programmdatei problemlos ausführen lassen?

+0

Könnte sein, dass Haskell erfordert, dass das Programm in der Unicode-Shell ausgeführt wird. –

+0

Meine Cmd-Shell druckt '" © "' fein aber würgt mit dem gleichen Fehler auf '" ഠഃ അ ഠൃ 3 "'. – chi

+0

Möglicherweise nützlich: http://stackoverflow.com/questions/22349139/utf8-output-from-powershell Ich bin kein PowerShell oder C# -Experte, aber die Tatsache, dass einige Zeichen Ersetzung auftritt ("C" statt "©") Wenn Sie Ihr C# -Programm ausführen, wird möglicherweise angezeigt, dass PowerShell nicht auf UTF-8 eingestellt ist ... @chi Diese Unicode-Zeichenfolge wird unter Mac OS X einwandfrei ausgegeben. Ich benutze bash über Terminal, das UTF-8 verwenden soll. – Jubobs

Antwort

2

Ich denke, dies sollte als ein Fehler in GHC zählen, aber es gibt einen Workaround. Die Standardcodierung für alle Handles in einem GHC-Programm (mit Ausnahme der im Binärmodus geöffneten Handles) ist nur die Codierung, die von der Konsole ohne Fehlerbehandlung akzeptiert wird. Glücklicherweise können Sie Fehlerbehandlung mit etwas wie diesem hinzufügen.

makeSafe h = do 
    ce' <- hGetEncoding h 
    case ce' of 
    Nothing -> return() 
    Just ce -> mkTextEncoding ((takeWhile (/= '/') $ show ce) ++ "//TRANSLIT") >>= 
     hSetEncoding h 

main = do 
    mapM_ makeSafe [stdout, stdin, stderr] 
    -- The rest of your main function. 
+0

Vielen Dank. Ich habe jetzt keine Ausnahme, aber ich habe immer noch nicht das, was ich erwartet habe. Ich habe die '. ? Erste Sekunde, 2014 Ausgabe statt '© First Second, 2014'. –

+1

Es wird "?" weil die Kodierung, die von Ihrer Konsole benutzt wird, nicht den "©" Charakter hat, aber ich habe noch nie zuvor "" hinzugefügt und ich weiß nicht was dort vor sich geht. Sie können diese Antwort auch mit der @ bheklilr-Antwort kombinieren, um die Codierung Ihrer Konsole zu ändern, die den von Ihnen benötigten Zeichensatz enthält (Codepage 65001 verwendet die gleiche Methode wie utf-8 für die Zeichengröße, kann aber leider nur utf-8 genannt werden es ist dir egal, welche Zeichen tatsächlich angezeigt werden) –

+0

Die '.' existiert, wenn ich meinen Code in * ghci * lade und die' main' Funktion manuell ausführe. Wenn ich meinen Code als EXE-Datei kompiliere, habe ich den ' Text nicht. Vielen Dank. –

7

Unter Windows besteht die Behebung darin, der Shell mitzuteilen, dass sie code page 65001 (instructions here) verwenden soll, was Windows in den "UTF-8-Modus" versetzt. Es ist nicht perfekt, aber für die meisten Charaktere sollte man sehen, dass Unicode-Charaktere viel besser behandelt werden.

+3

Die andere Hälfte der Frage lautet: "Warum stürzt ein GHC-Binärcode ab, anstatt auf eine Nicht-Unicode-Ausgabe zurückzugreifen, wie .NET-Binärdateien?" GHC kann [das Gebietsschema des Systems ermitteln] (http://hackage.haskell.org/package/base-4.7.0.2/docs/GHC-IO-Encoding.html#v:getLocaleEncoding); wir sollten theoretisch in der Lage sein, die Kodierungsumwandlung durchzuführen und einen Absturz zu vermeiden. Ich frage mich, ob sich jemand darum gekümmert hat. –

Verwandte Themen