我意识到我的文本中的重音会转换为 。 我把它煮成了下面的例子,其中 写入(并覆盖)文件test.txt。
它只使用Data.Text中的方法 处理unicode文本。我检查了两个源文件 以及输出文件以utf8编码。
{-# LANGUAGE OverloadedStrings #-}
import Prelude hiding (writeFile)
import Data.Text
import Data.Text.IO
someText :: Text
someText = "Université"
main :: IO ()
main = do
writeFile "test.txt" someText
运行代码后,test.txt包含:Universit 。 在ghci中,我得到以下内容
*Main> someText
"Universit\233"
这已编码错误吗?我还发现了对 in的评论 https://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text.html, 但我仍然不知道如何纠正上面的例子。
如何在OverloadedString中使用重音并正确地将它们写入文件?
答案 0 :(得分:5)
这与Data.Text
无关,当然也与OverloadedStrings
无关 - 两者都处理UTF-8-Unicode就好了。
但Data.Text.IO
不会写BOM或任何表示编码的内容,即文件实际上只包含文本。在任何现代系统中,这意味着它将采用原始的UTF-8形式:
sagemuej@sagemuej-X302LA:~$ xxd test.txt
00000000: 556e 6976 6572 7369 74c3 a9 Universit..
sagemuej@sagemuej-X302LA:~$ cat test.txt
Université
因此,根据您打开文件的编辑器,可能会猜错编码,这显然是您的问题。在Linux上,UTF-8长期以来一直是标准,所以这里没有问题,但Windows并不是最新的。不过,应该可以在任何编辑器中手动选择编码。
事实上,Data.Text.IO.writeFile
将使用您的locale来决定如何对文件进行编码。 Everybody should have UTF-8现在作为他们的语言环境,如果你不想改变它。
要在文件中获取BOM并排除此类问题,请使用utf8_bom
。
关于你在GHCi中看到的输出:Show
实例在工作;它将任何类似字符串的值转换为最安全的可想象的形式,即对于'é'
碰巧为'\233'
的转义序列不是ASCII的任何东西。同样不是Text
特有的,事实上即使对于单个字符也是如此:
Prelude> 'é'
'\233'
Prelude> putChar '\233'
é
当您对字符串类型使用direct-IO-output操作时,这种转义永远不会发生,即putChar
,putStr
或putStrLn
。
Prelude> import qualified Data.Text.IO as Txt
Prelude Txt> Txt.putStrLn "Université"
Université