2014-12-23 7 views
10

Char è il tipo per caratteri Unicode in Haskell e String è semplicemente [Char] (ovvero un elenco di articoli Char). Ecco qualche semplice codice:Errore di run-time durante il tentativo di stampare un carattere Unicode

main = putStrLn "©" -- Unicode string 

Questo codice compila bene, ma ho l'eccezione di runtime quando l'eseguo in PowerShel.exe o cmd.exe:

app. exe: commitBuffer: argomento non valido (carattere non valido)

Perché ciò accade? Stranamente, quando faccio lo stesso in C#, non ottengo alcuna eccezione:

Console.WriteLine("©"); 

In .NET, caratteri Unicode sono troppo. PowerShell o cmd stampe c invece ©, ma almeno non ottengo eccezione. Come posso far funzionare senza problemi il mio eseguibile Haskell?

+0

Potrebbe essere che Haskell richiede che il programma venga eseguito nella shell Unicode. –

+0

La mia shell cmd stampa '" © "' bene ma si strozza con lo stesso errore su '" ഠഃ അ ഠൃ 3 "'. – chi

+0

Forse utile: http://stackoverflow.com/questions/22349139/utf8-output-from-powershell Non sono esperto di PowerShell o C#, ma il fatto che si verifichi una sostituzione di caratteri ("c" invece di "©") quando si esegue il programma C# potrebbe indicare che PowerShell non è impostato per utilizzare UTF-8 ... @chi Quella stringa Unicode viene stampata correttamente su Mac OS X; Uso bash tramite Terminal, che è impostato per utilizzare UTF-8. – Jubobs

risposta

2

Penso che questo dovrebbe essere un errore in GHC, ma c'è una soluzione alternativa. La codifica predefinita per tutti gli handle in un programma GHC (tranne quelli aperti in modalità binaria) è solo la codifica accettata dalla console senza gestione degli errori. Fortunatamente puoi aggiungere la gestione degli errori con qualcosa di simile.

makeSafe h = do 
    ce' <- hGetEncoding h 
    case ce' of 
    Nothing -> return() 
    Just ce -> mkTextEncoding ((takeWhile (/= '/') $ show ce) ++ "//TRANSLIT") >>= 
     hSetEncoding h 

main = do 
    mapM_ makeSafe [stdout, stdin, stderr] 
    -- The rest of your main function. 
+0

Grazie. Non ho fatto eccezione ora, ma ancora non ho le stesse cose che mi aspettavo. Ho ottenuto il '. ? First Second, 2014' output invece di '© First Second, 2014'. –

+1

Aggiunge "?" perché la codifica utilizzata dalla tua console non ha il carattere "©", ma non l'ho mai visto aggiungere "" prima e non so cosa sta succedendo lì. Puoi anche combinare questa risposta con la risposta di @ bheklilr per cambiare la codifica della tua console in qualcosa che ha il carattere di cui hai bisogno (codepage 65001 usa lo stesso metodo di utf-8 per notare la dimensione del personaggio, ma sfortunatamente può essere chiamato utf-8 se non ti importa quali caratteri vengono effettivamente visualizzati) –

+0

Il ' .' esiste quando carico il mio codice in * ghci * ed eseguo manualmente la funzione' main'. Se compilo il mio codice come file exe, non ho il testo '. Grazie. –

7

In Windows, la correzione indica alla shell di utilizzare code page 65001 (instructions here), che mette Windows in "modalità UTF-8". Non è perfetto, ma per la maggior parte dei personaggi dovresti vedere i caratteri unicode gestiti molto meglio.

+3

L'altra metà della domanda è "perché un errore di binario di GHC piuttosto che ricadere con grazia su output non Unicode come i binari .NET sembrano?" GHC può [capire le impostazioni locali del sistema] (http://hackage.haskell.org/package/base-4.7.0.2/docs/GHC-IO-Encoding.html#v:getLocaleEncoding); dovremmo teoricamente essere in grado di fare la conversione della codifica ed evitare crash. Mi chiedo se qualcuno l'abbia esaminato. –

Problemi correlati