2017-08-27 67 views
1

我意識到我的文本中的重音被轉換爲 。 我將它解釋爲下面的示例,其中 寫入(並覆蓋)文件test.txt。Haskell中的Utf8和重載字符串

它只使用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" 

這是已經編碼不正確?我還在 https://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text.html, 中發現了對 的評論,但我仍然不知道如何更正上述示例。

如何在OverloadedString中使用重音並將它們正確地寫入文件?

+0

字符串(和文字以及,我相信)在GHCI都逃脫「滑稽」字符後打印:這樣做是因爲,如果用戶鍵入'putStrLn(顯示字符串)''那裏做show'逸出和增加了引號。你可以用'putStrLn string'打印裸字符串/文本(記得使用'Data.Text.putStrLn'代替文本,而不是前奏) – chi

+0

ghci中的putStrLn顯示正確的重音,所以它必須是writeFile? – mna

回答

5

這與Data.Text無關,當然也不能與OverloadedStrings - 都處理UTF-8-Unicode就好了。

但是Data.Text.IO不會寫BOM或任何指示編碼的東西,即該文件實際上僅包含文本原樣。在任何現代企業制度,這意味着它會在原始UTF-8格式:

[email protected]:~$ xxd test.txt 
00000000: 556e 6976 6572 7369 74c3 a9    Universit.. 
[email protected]:~$ cat test.txt 
Université 

所以這取決於你開什麼編輯器文件,它可能猜測錯誤的編碼,而這顯然是您的問題。在Linux上,UTF-8一直是標準,所以這裏沒有問題,但Windows並不是最新的。不過,應該可以在任何編輯器中手動選擇編碼。

實際上,Data.Text.IO.writeFile將使用您的locale來決定如何對文件進行編碼。 Everybody should have UTF-8作爲他們的語言環境時下,如果你不請改變這一點。

要在您的文件中獲得物料清單並因此排除此類問題,請使用utf8_bom

關於您在GHCi中看到的輸出:這是Show實例在工作;它將任何類似字符串的值轉義爲最安全的想象形式,即任何不是ASCII的轉義序列,對於'é'恰好是'\233'。同樣不特定Text,其實你這甚至單個字符:當您使用直接IO輸出動作爲您的字符串類型

Prelude> 'é' 
'\233' 
Prelude> putChar '\233' 
é 

此轉義永遠不會發生,即putCharputStrputStrLn

Prelude> import qualified Data.Text.IO as Txt 
Prelude Txt> Txt.putStrLn "Université" 
Université 
+0

我在編輯器中打開了test.txt,並手動將編碼設置爲utf8。我仍然沒有聽到重音。我怎麼知道writeFile使用什麼編碼? – mna

+0

我以爲它總是UTF-8,但[根據文檔](http://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text-IO.html#g:2)它實際上使用您的區域設置來決定。我強烈建議您將您的語言環境設置爲UTF-8,並且再也不用擔心它。或者,你當然可以用你喜歡的任何編碼創建一個字節串(現在[你應該什麼都不用]除了UTF-8之外的任何東西](http://utf8everywhere.org/),所以......)。 – leftaroundabout

+0

的確,我的堆棧haskell安裝的語言環境未設置爲utf8。我不知道如何改變它,但可以使用「setLocaleEncoding utf8」在代碼中進行更改。 – mna