【问题标题】:Run-time exception when attempting to print a Unicode character尝试打印 Unicode 字符时出现运行时异常
【发布时间】:2014-12-23 08:25:55
【问题描述】:

Char 是 Haskell 中 Unicode 字符的类型,String 就是 [Char](即Char 项目的列表)。下面是一些简单的代码:

main = putStrLn "©" -- Unicode string

这段代码编译得很好,但是当我在 PowerShel.execmd.exe 中运行它时出现运行时异常:

app.exe: : commitBuffer: 无效参数(无效字符)

为什么会这样?奇怪的是,当我在 C# 中做同样的事情时,我也没有例外:

Console.WriteLine("©");

在 .NET 中,字符也是 Unicode。 PowerShellcmd 打印 c 而不是 ©,但至少我没有例外。如何让我的 Haskell 可执行文件顺利运行?

【问题讨论】:

  • 可能是 Haskell 要求该程序在 unicode shell 中运行。
  • 我的 cmd shell 打印 "©" 很好,但在 "ഠഃ അ ഠൃ ൩" 上出现同样的错误。
  • 可能有用:stackoverflow.com/questions/22349139/… 我不是 PowerShell 或 C# 专家,但是当您运行 C# 程序时发生某些字符替换(“c”而不是“©”)这一事实可能表明PowerShell 未设置为使用 UTF-8...@chi Unicode 字符串在 Mac OS X 上打印得很好;我通过终端使用 bash,它设置为使用 UTF-8。
  • @Jubobs 实际上,在 linux 上,终端也设置为 UTF-8,我从来没有遇到过问题。 @Bush 如果您只想避免异常,您可以在终端中使用 chcp 65001 ——不过,所有非 ascii 字符都将不可读。
  • @Bush 您是否使用chcp.com 65001 设置了代码页?

标签: haskell ghc


【解决方案1】:

我认为这应该算作 GHC 中的一个错误,但有一种解决方法。 GHC 程序中所有句柄的默认编码(除了以二进制模式打开的句柄)只是控制台接受的编码,没有错误处理。幸运的是,您可以使用类似的方式添加错误处理。

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.

【讨论】:

  • 谢谢。我现在也不例外,但我仍然没有我所期望的那样。我得到了&lt;interactive&gt;. ? First Second, 2014 输出而不是© First Second, 2014
  • 它正在添加“?”因为您的控制台使用的编码没有“©”字符,但我以前从未见过它添加“”,我不知道那里发生了什么。您还可以将此答案与@bheklilr 的答案结合使用,以将控制台的编码更改为具有您需要的字符的内容(代码页 65001 使用与 utf-8 相同的方法来记录字符大小,但不幸的是,如果你不在乎实际显示的是什么字符)
  • 当我将代码加载到 ghci 并手动运行 main 函数时,&lt;interactive&gt;. 存在。如果我将我的代码编译为 exe 文件,我没有 ` 文本。谢谢。
【解决方案2】:

在 Windows 上,解决方法是告诉 shell 使用 code page 65001 (instructions here),这会将 Windows 置于“UTF-8 模式”。它并不完美,但对于大多数字符,您应该会看到 unicode 字符的处理效果要好得多。

【讨论】:

  • 问题的另一半是“为什么 GHC 二进制文件会崩溃,而不是像 .NET 二进制文件那样优雅地退回到非 Unicode 输出?” GHC可以figure out the system locale;我们理论上应该能够进行编码转换并避免崩溃。我想知道是否有人调查过。
猜你喜欢
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 2014-12-30
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多