2013-02-27 18 views
6

Sto scrivendo un'applicazione terminale (console) che dovrebbe includere testo unicode arbitrario.determina se un carattere Unicode è a larghezza intera o a metà larghezza in C++

I terminali utilizzano in genere un carattere monospaziato (larghezza fissa), in modo da racchiudere un testo, è appena più che contare i caratteri e osservare se una parola rientra in una riga o meno e agire di conseguenza.

Il problema è che nella tabella Unicode sono presenti caratteri a larghezza intera che occupano la larghezza di 2 caratteri in un terminale.

Il conteggio di questi vedrebbe 1 carattere unicode, ma il carattere stampato è largo 2 caratteri "normali" (metà larghezza), interrompendo la routine di avvolgimento in quanto non è a conoscenza di caratteri che occupano il doppio della larghezza.

Come esempio, questo è un personaggio fullwidth (U + 3004, il simbolo JIS)

 
〄 
12 

Esso non occupa l'intera larghezza di 2 caratteri qui anche se è preformattati, ma fa uso di due volte la larghezza di un carattere occidentale in un terminale.

Per far fronte a questo, devo distinguere tra caratteri a larghezza intera o metà larghezza, ma non riesco a trovare un modo per farlo in C++. È davvero necessario conoscere tutti i caratteri a larghezza intera nella tabella Unicode per aggirare il problema?

+1

Rilevante http://www.icu-project.org/apiref/icu4c/uchar_8h.html#a3376f0d34bb23c54671859f1978b4226 e http://www.unicode.org/reports/tr11/ –

+0

Per quale sistema operativo/piattaforma? –

+0

Mi dispiace, mi sono perso. Il sistema operativo è Linux. – Noice

risposta

6

È necessario utilizzare ICU u_getIntPropertyValue con la proprietà UCHAR_EAST_ASIAN_WIDTH.

Ad esempio:

bool is_fullwidth(UChar32 c) { 
    int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH); 
    return width == U_EA_FULLWIDTH || width == U_EA_WIDE; 
} 

Nota che se la libreria grafica supporta combinando caratteri allora si dovrà prendere in considerazione quelle pure quando si determina il numero di cellule di una sequenza utilizza; ad esempio e seguito da U+0301 COMBINAZIONE ACCENTO ACUTO occuperà solo 1 cella.

+0

Sto per sostituire tutte le chiamate in ICU adesso per minimizzare le dipendenze. Forse posso creare una tabella di tutti i caratteri a larghezza intera con l'aiuto del metodo u_getIntPropertyValue. Grazie per il suggerimento ai personaggi che combinano. Verificherò se questo vale anche per i terminali. – Noice

+0

@Noice Potrebbe non essere più pertinente per te, ma di recente ho messo insieme gli intervalli di caratteri per una domanda simile qui: http://stackoverflow.com/a/15651264/777186 – jogojapan

Problemi correlati