2009-12-22 13 views
20

Quando si utilizza l'interprete Scala (vale a dire l'esecuzione del comando 'scala' sulla riga di comando), io non sono in grado di stampare correttamente i caratteri Unicode. Ovviamente a-z, A-Z, ecc. Sono stampati correttamente, ma ad esempio € o ƒ è stampato come un?.stampa Unicode da Scala interprete

print(8364.toChar) 

risultati in? invece di €. Probabilmente sto facendo qualcosa di sbagliato. Il mio terminale supporta i caratteri utf-8 e anche quando reindirizzo l'output a un file separato e lo apro in un texteditor,? È visualizzato.

tutto questo succede su Mac OS X (Snow Leopard, 10.6.2) con Scala 2.8 (nightly build) e Java 1.6.0_17)

+0

In quale sistema operativo stai eseguendo l'interprete? E quale versione di Scala? –

+0

Aggiunto nel mio post originale –

risposta

16

ho trovato la causa del problema, e una soluzione per farlo funzionare come dovrebbe. Come già sospettavo dopo aver postato la mia domanda e aver letto la risposta di Calum e problemi con la codifica su Mac con un altro progetto (che era in Java), la causa del problema è la codifica predefinita usata da Mac OS X. Quando si avvia scala interprete, utilizzerà la codifica predefinita per la piattaforma specificata. Su Mac OS X, questo è Macromano, su Windows è probabilmente CP1252. È possibile controllare questo digitando il seguente comando nell'interprete scala:

scala> System.getProperty("file.encoding"); 
res3: java.lang.String = MacRoman 

Secondo il test scala, è possibile fornire le proprietà Java utilizzando l'opzione -D. Tuttavia, questo non funziona per me. Ho finito per impostare la variabile d'ambiente

JAVA_OPTS="-Dfile.encoding=UTF-8" 

Dopo aver eseguito scala, il risultato del comando precedente darà il seguente risultato:

scala> System.getProperty("file.encoding") 
res0: java.lang.String = UTF-8 

Ora, la stampa di caratteri speciali funziona come previsto:

print(0x20AC.toChar)    
€ 

Quindi, non è un bug in Scala, ma un problema con le codifiche di default. A mio parere, sarebbe meglio se per impostazione predefinita UTF-8 fosse utilizzato su tutte le piattaforme. Nella mia ricerca di una risposta se questo è considerato, mi sono imbattuto in un discussion sulla mailing list di Scala su questo problema.Nel primo messaggio, si propone di utilizzare UTF-8 di default su Mac OS X quando file.encoding segnala Macroman, poiché UTF-8 è il set di caratteri predefinito su Mac OS X (mi chiedo perché il parametro file.encoding per default sia impostato su Macroman, probabilmente questa è un'eredità di Mac OS prima del rilascio di 10?). Non penso che questa proposta farà parte di Scala 2.8, poiché Martin Odersky wrote è probabilmente meglio mantenere le cose come sono in Java (ad esempio, onorare la proprietà file.encoding).

+0

Per quotare Sun: _La proprietà "file.encoding" non è richiesta dalle specifiche della piattaforma J2SE; è un dettaglio interno delle implementazioni di Sun e non deve essere esaminato o modificato dal codice utente. È anche inteso per essere di sola lettura; è tecnicamente impossibile supportare l'impostazione di questa proprietà su valori arbitrari sulla riga di comando o in qualsiasi altro momento durante l'esecuzione del programma. http://bugs.sun.com/view_bug.do?bug_id=4163515 Quindi, non è supportato, potrebbe non funzionare su tutte le JVM e potrebbe avere effetti collaterali indesiderati. – McDowell

+1

Un modo per fare ciò evitando il problema che i flag di McDowell è quello di avvolgere System.out PrintStream (che funziona ancora come OutputStream non elaborato) con un PrintStream che utilizza la codifica desiderata, quindi utilizzarlo, ad esempio "val myOut = nuovo PrintStream (System.out, "UTF-8"); myOut.print (0x20AC.toChar) ". Questo dovrebbe sempre funzionare. Vorrei modificare questo in ma non credo di avere il karma per quel genere di cose. – Calum

+1

@Calum: è interessante vedere se funziona su Mac; non funziona molto bene su Windows, ma potrebbe trattarsi di un problema specifico della piattaforma: http://illegalargumentexception.blogspot.com/2009/04/i18n-unicode-at-windows-command-prompt.html#charsets_javaconsole – McDowell

3

Ok, almeno in parte, se non tutti, del problema ecco che 128 non è il codice Unicode per Euro. 128 (o 0x80 poiché hex sembra essere la norma) è U+0080 <control>, cioè non è un carattere stampabile, quindi non sorprende che il terminale abbia problemi a stamparlo.

valore di codice di Euro è 0x20AC (o in decimale 8364), e che sembra funzionare per me (io sono su Linux, su un notturno di 2,8):

scala> print(0x20AC.toChar) 
€ 

Un altro test divertente è quello di stampare il Unicode carattere pupazzo di neve:

scala> print(0x2603.toChar) 
☃ 

128 € come è apparentemente un carattere esteso da una delle pagine di codice di Windows.

ho avuto l'altro personaggio che hai menzionato lavorare troppo:

scala> 'ƒ'.toInt 
res8: Int = 402 

scala> 402.toChar 
res9: Char = ƒ 
+0

Hai ragione riguardo al numero sbagliato per il simbolo Euroo. Tuttavia, non funziona ancora per me: scala> print (0x20AC.toChar) ? Ma se funziona di notte, probabilmente è un problema con il mio sistema o forse è stato risolto con le nuove versioni di Scala 2.8. Aggiornerò un'indagine più approfondita. –

+0

L'ho verificato su night 'di oggi (2.8.0.r20300-b20091223020158) e' print (0x20AC.toChar) 'stampa un punto interrogativo proprio come tutte le altre 2.8 versioni che ho in giro. – p3t0r

+0

Sono su OSX 10.6.2 a proposito. – p3t0r

0

Per la stampa di Windows a riga di comando (cmd):

  1. set JAVA_OPTS="-Dfile.encoding=UTF-8"
  2. chcp 65001

Articolo 2 significa UTF-8

Se non si desidera stampare ogni volta " chcp 65001 ", è possibile modificare/aggiungere valore nel registro di Windows in questo modo:

  1. comando Esegui regedit
  2. record di find [Processor HKEY_CURRENT_USER \ Software \ Microsoft \ Command]
  3. Nuovo => Valore stringa
  4. Name = "AutoRun", Data = "65001 chcp" (senza virgolette)

(vedi https://superuser.com/a/482117/454417)

uso Windows 10 e Scala 2.11.8