简单 Haskell 代码中的错误字符编码
Wrong character encoding in simple Haskell code
我在 haskell 中遇到字符编码问题。这个简单的程序写错了结果。我在这里真正感兴趣的是强制我使用 ByteString 的编码函数。申请是:
import Data.ByteString.Char8 (unpack, pack)
import Data.ByteString.Lazy (toStrict)
import Data.Csv (encode) -- cabal install cassava
main = do
-- (middle character is polish diacritic letter)
putStrLn $ unpack $ pack "aća"
putStrLn $ unpack $ toStrict $ encode ["aća"]
它应该打印
aća
a,ć,a
而是写成
aa
a,Ä,a
这破坏了我的 CSV 编码应用程序。这发生在 Linux 无论我的区域设置如何
$ locale
LANG=pl_PL.UTF-8
LC_CTYPE="pl_PL.UTF-8"
LC_NUMERIC="pl_PL.UTF-8"
LC_TIME="pl_PL.UTF-8"
LC_COLLATE="pl_PL.UTF-8"
LC_MONETARY="pl_PL.UTF-8"
LC_MESSAGES="pl_PL.UTF-8"
LC_PAPER="pl_PL.UTF-8"
LC_NAME="pl_PL.UTF-8"
LC_ADDRESS="pl_PL.UTF-8"
LC_TELEPHONE="pl_PL.UTF-8"
LC_MEASUREMENT="pl_PL.UTF-8"
LC_IDENTIFICATION="pl_PL.UTF-8"
LC_ALL=pl_PL.UTF-8
或
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
我想知道的是如何将编码 (Data.ByteString.Lazy.ByteString) 的输出转换为字符串,以便我可以使用例如将其写入文件writeFile 函数。
您应该只使用 Data.ByteString.Lazy.putStr
而不是 putStrLn . unpack . toStrict
。无需经过 Text
.
Data.ByteString.Char8.unpack
将值为 n 的字节转换为值为 n 的 Unicode 代码点。不要在(非 ASCII)UTF-8 编码文本上使用它!
编辑:我看到你说你想将 encode
的结果转换为字符串以将其写入文件。不要那样做,而是使用像 Data.ByteString.Lazy.writeFile
这样的 IO 函数。
我在 haskell 中遇到字符编码问题。这个简单的程序写错了结果。我在这里真正感兴趣的是强制我使用 ByteString 的编码函数。申请是:
import Data.ByteString.Char8 (unpack, pack)
import Data.ByteString.Lazy (toStrict)
import Data.Csv (encode) -- cabal install cassava
main = do
-- (middle character is polish diacritic letter)
putStrLn $ unpack $ pack "aća"
putStrLn $ unpack $ toStrict $ encode ["aća"]
它应该打印
aća
a,ć,a
而是写成
aa
a,Ä,a
这破坏了我的 CSV 编码应用程序。这发生在 Linux 无论我的区域设置如何
$ locale
LANG=pl_PL.UTF-8
LC_CTYPE="pl_PL.UTF-8"
LC_NUMERIC="pl_PL.UTF-8"
LC_TIME="pl_PL.UTF-8"
LC_COLLATE="pl_PL.UTF-8"
LC_MONETARY="pl_PL.UTF-8"
LC_MESSAGES="pl_PL.UTF-8"
LC_PAPER="pl_PL.UTF-8"
LC_NAME="pl_PL.UTF-8"
LC_ADDRESS="pl_PL.UTF-8"
LC_TELEPHONE="pl_PL.UTF-8"
LC_MEASUREMENT="pl_PL.UTF-8"
LC_IDENTIFICATION="pl_PL.UTF-8"
LC_ALL=pl_PL.UTF-8
或
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
我想知道的是如何将编码 (Data.ByteString.Lazy.ByteString) 的输出转换为字符串,以便我可以使用例如将其写入文件writeFile 函数。
您应该只使用 Data.ByteString.Lazy.putStr
而不是 putStrLn . unpack . toStrict
。无需经过 Text
.
Data.ByteString.Char8.unpack
将值为 n 的字节转换为值为 n 的 Unicode 代码点。不要在(非 ASCII)UTF-8 编码文本上使用它!
编辑:我看到你说你想将 encode
的结果转换为字符串以将其写入文件。不要那样做,而是使用像 Data.ByteString.Lazy.writeFile
这样的 IO 函数。