2012-01-28 59 views
1

我使用hsparql庫運行返回德文文本的查詢;並因此返回iso-8859-1特殊字符。查詢結果中的iso-8859-1特殊字符錯誤

我使用writeFile將查詢結果寫入文件,但未正確顯示特殊字符。 (查看與emacs的文件時)

當我不是寫show函數的輸出到一個文件,我得到下面的輸出:

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

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

如何正確地將特殊字符寫入文件? (例如「Büro」正確顯示在文件輸出中。)

編輯: 我知道show顯示轉義字符。直接使用writeFile不起作用,我必須檢查錘子答案中給出的鏈接以找到修復。

EDIT2: 刪除,是錯誤的方法。

編輯3: 錘子的答案是正確的。找到解決方案只花了10分鐘,但我需要適應和集中。

我擡起頭IO在link

的解決方案是(文學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 
+0

對於範圍爲0x80 - 0xBF的特殊字符,即特殊引號,應該使用** windows-1252 **。 – 2012-01-28 01:08:01

回答

4

不要使用show,如果你不想要的東西逃脫做。它意味着輕量級的序列化,並且會轉義一些特殊字符以及ASCII範圍之外的字符。如果您直接使用writeFile,它應該使用當前語言環境的默認編碼。

要更好地控制編碼,請參閱the System.IO documentation

+0

謝謝你的回答!將於明天展望... – mrsteve 2012-01-28 01:28:10

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中顯示爲這樣的(如果使用的字體具有字形),並作爲"\195\188"時在ghci中使用show

如果數據庫發送UTF-8據信Latin1的並且被轉換爲UTF-8,兩個字節將被轉換成兩個兩字節序列,[195,131] ([\xC3,\x83])[194,188] ([\xC2,\xBC]),這將在一個UTF-8的區域設置再次解釋爲兩個字符ü

如果數據庫發送的latin1被認爲是UTF-8,則由「ür」產生的字節序列[252,114] ([\xFC,\x72])將是導致編碼錯誤的非法字節序列。我不知道任何錯誤處理機制會將違規的252轉換爲[195,188],所以這不太可能是發生的事情。

要了解發生了什麼,請在十六進制編輯器中查看該文件(或者在unixish平臺上使用xxd)並檢查您的語言環境。問題的解決方案應該是將句柄設置爲正確的編碼,正如@hammar鏈接到的文檔部分所暗示的那樣。

+0

非常感謝您的澄清。我認爲它會幫助來自搜索引擎的人。 – mrsteve 2012-02-01 20:17:04