2015-08-27 15 views
10

Si prega di indicare innanzitutto che questo problema è strettamente correlato all'operatore perl diamond che accetta input che è stato digitato direttamente sulla tastiera.Il carattere di Umlaut non è accettato tramite tastiera (codepage 65001, UTF-8) da leggere con script perl

Avevo parlato dell'operatore perl diamond accettando l'input che era stato convogliato o in altro modo dal testo di un file, quindi sì, questo sarebbe un duplicato della domanda 519309 - How do I read Utf-8 with diamond operator.

Tuttavia, non si tratta di dati in pipe o file, ma piuttosto di input che sono stati digitati direttamente sulla tastiera. Pertanto, io sostengo, questa domanda non è un duplicato di 519309.

Ecco i dettagli della mia domanda:

Sto cercando di utilizzare i caratteri dieresi ('A', 'O', 'u', ...) sulla mia tastiera.

ho una molto semplice script perl che accetta una linea dalla tastiera e poi subito a stampa fuori di nuovo allo schermo:

Se uso caratteri di dieresi con tabella codici 1252, quindi tutto funziona come previsto:

C:\>chcp 1252 & perl -CS -we"print '*** '; $txt = <>; print '--- ', $txt;" 
Page de codes active : 1252 
*** ü 
--- ü 

Tuttavia, se uso gli stessi caratteri di dieresi con tabella codici 65001 (UTF-8), allora ottengo un valore non inizializzato avvertimento e la dieresi non viene accettata:

C:\>chcp 65001 & perl -CS -we"print '*** '; $txt = <>; print '--- ', $txt;" 
Page de codes active : 65001 
*** ü 
Use of uninitialized value $txt in print at -e line 1. 
--- 

Se il tubo l'umlaut nel mio programma perl, quindi non ho alcun problema:

C:\>chcp 65001 & echo ü | perl -CS -we"print '*** '; $txt = <>; print '--- ', $txt;" 
Page de codes active : 65001 
*** --- ü 

Perché ottengo questo avvertimento con tabella codici 65001 (UTF-8)?

Sto usando Windows 7 x64, con Strawberry Perl 5.22.

Solo per la cronaca, se utilizzo comandi batch puri (ovvero non utilizzo perl), quindi posso digitare correttamente i caratteri di umlaut con codepage 65001 (UTF-8).

C:\>chcp 65001 & set /p txt=*** & echo --- %txt% 
Page de codes active : 65001 
*** ü 
--- ü 

La questione è davvero: perché non è in grado di accettare perl caratteri di dieresi da tastiera con tabella codici 65001, mentre lo stesso input da tastiera, la stessa tabella codici 65001, funziona bene come un comando batch DOS puro?

Sembra esserci qualcosa di fondamentalmente diverso tra i caratteri di umlaut in pipe e la digitazione di caratteri di umlaut direttamente dalla tastiera.

Perché la digitazione di un carattere di umlaut sulla tastiera non funziona, mentre la stessa cosa funziona perfettamente come un personaggio in pipe?

+0

Avete provato l'opzione '-CS'? ('perl -CS -we') per fare STDIN e STDOUT usare la codifica UTF-8 –

+0

Ho provato perl -CS -we - questo funziona perfettamente per la stampa su STDOUT, ma per qualche motivo, non ha alcun effetto su STDIN (vale a dire: ho ancora esattamente lo stesso problema - valore non inizializzato) – user2288349

+1

'CHCP 65001' il supporto per utf-8 in cmd è fragile se usato con applicazioni esterne come' perl'. Ecco dove i wrapper come ConEmu tornano a portata di mano. – wOxxOm

risposta

2

tenta di modificare font della console a "Console Lucida"

Inoltre si può tentare di eseguire chcp 65001 in consolle. Questo comando imposterà i caratteri su UTF-8

Se si ottiene una visualizzazione errata, installare il carattere richiesto nel sistema.

Maggiori dettagli here

realtà il problema non appartiene a Perl.Appartiene al terminale di Windows. Prova come funziona in this console. È possibile accedere ad alcuni file di dati binari letti dall'input e confrontare questi due casi (terminale VS cygwin)

1

Questo è un bug Microsoft. Le API di Windows ReadFile() e ReadConsoleA() restituiscono sempre 0 byte letti (che indica EOF) nella codepage 65001. Per i dettagli vedere this blog.
Poiché Microsoft non risolverà questo problema, l'unica risposta disponibile è dire ai manutentori di Perl di passare all'uso di ReadConsoleW() e convertire i caratteri wide risultanti in utf-8 con WideCharToMultiByte (CP_UTF8, ...).