Run-time exception when attempting to print a Unic

2019-04-03 19:38发布

Char is the type for Unicode characters in Haskell, and String is simply [Char] (i.e. a list of Char items). Here is some simple code:

main = putStrLn "©" -- Unicode string

This code compiles fine, but I get the runtime exception when I run it in the PowerShel.exe or cmd.exe:

app.exe: : commitBuffer: invalid argument (invalid character)

Why does this happen? Weirdly enough, when I do the same in C#, I get no exception:

Console.WriteLine("©");

In .NET, chars are Unicode too. PowerShell or cmd prints c instead ©, but at least I get not exception. How can I get my Haskell executable to run smoothly?

标签: haskell ghc
2条回答
贪生不怕死
2楼-- · 2019-04-03 19:44

I think this should count as a bug in GHC, but there is a workaround. The default encoding for all handles in a GHC program (except those opened in Binary mode) is just the encoding accepted by the console with no error handling. Fortunately you can add error handling with something like this.

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.
查看更多
够拽才男人
3楼-- · 2019-04-03 19:44

On Windows, the fix is to tell the shell to use code page 65001 (instructions here), which puts Windows in "UTF-8 mode". It's not perfect, but for most characters you should see unicode characters handled much better.

查看更多
登录 后发表回答