查询结果中出现iso-8859-1特殊字符错误

时间:2012-01-28 00:50:09

标签: haskell

我使用hsparql库来运行返回德语文本的查询;因此返回iso-8859-1特殊字符。

我使用writeFile将查询结果写入文件,但未正确显示特殊字符。 (使用emacs查看文件时)

当我将show函数的输出写入文件时,我得到以下输出:

["B\195\188ro", ...]

打印出它意味着的特殊字符:["Büro", ....]

如何正确地将特殊字符写入文件? (例如,“Büro”在文件输出中正确显示。)

编辑: 我知道这个节目写了逃脱的角色。直接使用writeFile不起作用,我必须检查锤子的答案中给出的链接以找到修复程序..

EDIT2: 删除,是错误的方法。

EDIT3: 锤子回答是正确的。只需要10分钟就可以找到解决方案,但我需要保持健康和专注。

我在link

中查找了IO

解决方案是(识字haskell):

> writeAllLabels = do

Running my Query (not shown, accesses the RDF TrippleStore):
>             res <- (selectStr33 (unlines qAllLabels))

>             outh <- openFile "/tmp/haskell_output.txt" WriteMode

this is the important line. If I would write "utf8" her instead of "latin1", I would get the wrong result again, i.e. as before asking the question...
>             hSetEncoding outh latin1

>             hPutStrLn outh res
>             hClose outh

2 个答案:

答案 0 :(得分:4)

如果您不希望事情被转义,请不要使用show。它适用于轻量级序列化,可以转义许多特殊字符以及ASCII范围之外的字符。如果直接使用writeFile,则应使用当前区域设置的默认编码。

要对编码进行更细粒度的控制,请参阅the System.IO documentation

答案 1 :(得分:2)

看起来好像你的数据库发送一个UTF-8编码的字符串,但它被认为是latin1编码,所以它再次被编码,或者数据库发送UTF-8,你的语言环境是latin1(或另一个单字节)编码)或者也许UCS-2 / UTF-16(如果你在Windows上,它可能是后者)。

字符'ü'是代码点252,其latin1编码是字节252 (\xFC),UTF-8编码是双字节序列[195,188] ([\xC3,\xBC])

如果数据库发送UTF-8并且您的语言环境是latin1,则双字节序列将被解释为两个字符ü并在emacs中显示(如果使用的字体具有字形),并且在ghci中使用"\195\188"时为show

如果数据库发送被认为是latin1的UTF-8,并且转换为UTF-8,那么这两个字节将被转换为两个双字节序列[195,131] ([\xC3,\x83])[194,188] ([\xC2,\xBC]),将UTF-8语言环境再次解释为两个字符ü

如果数据库发送被认为是UTF-8的latin1,则由“ür”引起的字节序列[252,114] ([\xFC,\x72])将是导致编码错误的非法字节序列。我不知道任何错误处理机制会将违规的252转换为[195,188],所以这不太可能是正在发生的事情。

要了解发生了什么,请在十六进制编辑器中查看该文件(如果在unixish平台上,请使用xxd)并检查您的语言环境。问题的解决方案应该是将句柄设置为正确的编码,正如@hammar链接到的文档部分所暗示的那样。