使用Haskell输出UTF-8编码的ByteString

27

我试图将UTF-8编码的数据输出到控制台,但却感到非常困扰。

使用String,我已经成功地完成了这个任务,但现在我想用ByteString来完成同样的事情。有没有一种好的快速方法可以做到这一点?

这是目前我的代码,但它不起作用:

import Prelude hiding (putStr)
import Data.ByteString.Char8 (putStr, pack)

main :: IO ()
main = putStr $ pack "čušpajž日本語"

它输出 uapaj~�,�,呃。

我想要最新版本的GHC 6.12.1的答案,尽管我也想听之前版本的答案。

谢谢!

更新:简单地读取和输出相同的UTF-8编码文本行似乎可以正常工作。(使用 Data.ByteString.Char8,我只需执行putStr =<< getLine。)但来自.hs文件内的压缩值,就像上面的示例一样,拒绝正确输出......我一定是做错了什么吗?


你在哪个平台上?Unicode 在类 UNIX 平台上现在运行得非常好;Windows 支持有些滞后。请参阅 System.IO 的文档:“(GHC 注意:在 Windows 上,我们目前不支持双字节编码;如果控制台的代码页不受支持,则 localeEncoding 将为 latin1。)” - ephemient
64位Linux。System.IO只能与String一起使用吗? - user12163
1
你不应该使用 BS.Char8,因为它假定是8位编码并截断多字节Unicode字符。除非你绝对知道 BS.Char8 是正确的数据类型(这包括知道为什么普通的ByteStrings明确不是那个用例的正确类型),否则请使用普通的ByteStrings。 - David
3个回答

27

utf8-string 支持字节串。

import Prelude hiding (putStr)
import Data.ByteString.Char8 (putStr)
import Data.ByteString.UTF8 (fromString)

main :: IO ()
main = putStr $ fromString "čušpajž日本語"

22

bytestrings是字节字符串。当它们被输出时,它们将被截断为8位,正如Data.ByteString.Char8文档中所描述的那样。您需要通过Hackage上的utf8-string包显式地将它们转换为UTF8,该包包含对bytestrings的支持。


然而,自2011年以来,您应该使用text包进行快速、紧凑的Unicode输出。GHC截断Unicode字符输出

您的示例变得简单了很多:

{-# LANGUAGE OverloadedStrings #-}

import qualified Data.Text    as T
import qualified Data.Text.IO as T

main = T.putStrLn "čušpajž日本語"

就像这样:

$ runhaskell A.hs
čušpajž日本語

utf8-string 只能用于字符串,而不能用于字节串吗? - user12163
3
可以,它也适用于字节串。请参见https://dev59.com/4HI95IYBdhLWcg3w7SpZ#2089195。 - Don Stewart

-2

不要啊啊啊啊。:( 但是,我感到困惑... 因为它似乎可以正常地与普通字符串一起工作? - user12163
无论这是什么,现在已经修复了。执行您链接页面上给出的示例按预期工作。区别在于我正在尝试输出UTF-8编码的ByteStrings,而不是UTF-8编码的字符串,这应该更有效率。请记住,我目前正在使用GHC 6.12.1,尽管我知道问题在GHC 6.10.4中也不存在。 - user12163
3
不,那其实不是问题所在。如果设置了区域设置为UTF8,则 GHC 6.12会执行String IO,这实际上解决了上述错误,但并非OP所问的问题。 - Don Stewart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接