Le type C 'char
' est 8-bits et restera 8-bits parce qu'il
désigne la plus petite unité de données adressable. Divers
aménagements sont disponibles :
Le standard ISO/ANSI C contient, dans une correction qui fut ajoutée
en 1995, un type de caractère codé sur 16 bits
`wchar_t
', un ensemble de fonctions comme celles contenues
dans <string.h>
et <ctype.h>
(déclarées respectivement dans <wchar.h>
et
<wctype.h>
), et un ensemble de fonctions de conversion
entre `char *
' et `wchar_t *
' (déclarées dans
<stdlib.h>
).
Voici de bonnes réferences pour cette interface de programmation :
Avantages de cette interface de programmation :
setlocale(LC_ALL,"");
.Inconvénients de cette interface de programmation :
Une variable `wchar_t
' peut être encodée en Unicode ou non.
Ceci dépend de la plateforme et quelquefois aussi des locales.
Une séquence multi-octets `wchar_t
' peut être encodée en
UTF-8 ou non selon la plateforme, et parfois selon les locales.
En détails, voici ce que la
Single Unix specification
dit à propos du type `wchar_t
' :
Tous les codes de caractères 16 bits dans un processus donné consistent en un nombre égal de bits. Ceci en contraste avec les caractères, qui peuvent être constitués d'un nombre variable d'octets. L'octet ou la séquence d'octets qui représentent un caractère peuvent aussi être représentés comme un code de caractère 16 bits. Les codes de caractères 16 bits fournissent donc une taille uniforme pour manipuler les données textuelles. Un code de caractère 16 bits ayant tous les bits à 0 est un code de caractère 16 bits nul (null), et termine une chaîne. La valeur des caractères larges pour chaque membre du "Portable Character Set" (i.e ASCII) est égale quand il est utilisé en tant que seul caractère dans un caractère entier (integer) constant. Les codes de caractères 16 bits pour les autres caractères dépendent des locales et de l'implémentation. Les octets modificateurs d'état n'ont pas de représentation en code de caractère 16 bits.
Une conséquence notable est que dans des programmes portables vous ne
devriez pas utiliser des caractères non-ASCII dans des chaînes
littérales.
Cela signifie que même si vous savez que les doubles guillemets ont
les codes U+201C et U+201D, vous ne devriez pas écrire une chaîne
littérale L"\u201cBonjour\u201d, dit il"
ou
"\xe2\x80\x9cBonjour\xe2\x80\x9d, dit il"
dans des programmes
C. Utilisez plutôt GNU gettext comme cela : gettext ("'Bonjour',
dit il")
, et créez une base de données de messages en.UTF-8.po
qui traduit "'Bonjour' dit il" en "\u201cBonjour\u201d, dit
il"
.
Voici une étude de la portabilité des aménagements ISO/ANSI C sur diverses implémentations d'Unix. La GNU glibc-2.2 les supportera tous, mais pour l'instant nous avons le tableau suivant.
Par conséquent je recommande l'utilisation des fonctions redémarrables et multithread-safe wcsr/mbsr. Oubliez les systèmes qui ne les ont pas (Irix, HP-UX, Aix), et utilisez le plug-in qui permet d'utiliser des locales UTF-8, libutf8_plug.so (voir ci dessous) sur les systèmes qui vous permettent de compiler des programmes qui utilisent ces fonctions wcrs/mbsr (Linux, Solaris, OSF/1).
Un avis similaire, donné par Sun dans http://www.sun.com/software/white-papers/wp-unicode/, section "Internationalized Applications with Unicode", est :
Pour internationaliser correctement une application utilisez les indications suivantes :
Si, pour une raison quelconque, vous devez vraiment supposer que
'wchar_t' est Unicode dans un morceau de code (par exemple, si vous
voulez faire un traitement spécial de certains caractères Unicode),
vous devriez rendre ce bout de code conditionnel selon le résultat de
is_locale_utf88()
. Autrement vous allez mettre la pagaille
dans le comportement de votre programme sur d'autres plateformes, ou
si d'autres locales sont utilisées.
La fonction is_locale_utf8()
est déclarée dans
utf8locale.h
et définie dans
utf8locale.c.
Une implémentation portable de l'API ISO/ANSI C, qui supporte les locales 8-bits et les locales UTF-8, peut être trouvée dans libutf8-0.5.2.tar.gz
Avantages :
Le système d'exploitation Plan9, une variante d'Unix, utilise UTF-8
comme encodage dans toutes ses applications. Son type de caractère
large est appelé 'Rune
', pas 'wchar_
'. Des parties ce ses
bibliothèques, écrites par Rob Pike et Howard Trikey, sont
disponibles à
ftp://ftp.cdrom.com/pub/netlib/research/9libs/9libs-1.0.tar.gz.
Une autre bibliothèque similaire, écrite par Alistair G. Crook, est à
ftp://ftp.cdrom.com/pub/NetBSD/packages/distfiles/libutf-2.10.tar.gz.
En particulier, chacune de ces bibliothèques contient un moteur
d'expressions rationnelles qui comprend l'UTF-8.
Désavantages de cette API :
La bibliothèque QT-2.0 http://www.troll.no/ contient la classe QString qui est totalement Unicode. Vous pouvez utiliser les fonctions membres QString::utf8 et QString::fromUtf8 pour convertir depuis/vers un texte encodé en UTF-8. Les fonctions membres QString::ascii et QString::latin1 ne devraient plus être utilisées.
Les bibliothèques mentionnées précédemment implémentent des versions des concepts ASCII qui comprennent Unicode. Voici des bibliothèques qui traitent des concepts Unicode, comme titlecase (Une troisième casse de lettres, différente des majuscules et des minuscules), la distinction entre la ponctuation et les symboles, la décomposition canonique, les classes combinables, le classement canonique et d'autres choses du même genre.
La bibliothèque ucdata de Mark Leisher http://crl.nmsu.edu/~mleisher/ucdata.html s'occupe des propriétés des caractères, de la conversion de la casse, de la décomposition, des classes combinées.
Ce sont les classes IBM pour Unicode. http://www.alphaworks.ibm.com/tech/icu/. Une bibliothèque très détaillée comprenant des chaînes de caractères Unicode, des paquets de ressources, des formateurs de nombres, de date, d'heure et de messages, des assemblages, des assembleurs de messages et plus encore. Beaucoup de locales sont supportées. Cette bibliothèque est portable pour Unix et Win32, mais compilera sans intervention ("out of the box") seulement avec la libc6, pas la libc5.
La librairie Unicode de GNOME http://cvs.gnome.org/lxr/source/libunicode/ de Tom Tromey entre autres. Elle couvre la conversion du jeu de caractères, les propriétés des caractères, la décomposition.
Deux bibliothèques de conversion qui supportent UTF-8 et un grand nombre de de jeux de caractères 8-bits, sont disponibles :
ftp://ftp.gnu.org/pub/gnu/glibc/glibc-2.1.1.tar.gz.
Avantages :
ftp://ftp.gnu.org/pub/gnu/recode/recode-3.5.tar.gz.
Avantages :
Problèmes :
libutf-8, de G.Adam.Stanislav
<adam@whizkidtech.net>
contient quelques fonctions pour la conversion depuis/vers des flux
"FILE*".
http://www.whizkidtech.net/i18n/libutf-8-1.0.tar.gz
Avantages :
Problèmes :
Java supporte Unicode en interne. Le type 'char' désigne un caractère Unicode, et la classe 'java.lang.String' désigne une chaîne de caractères construite à partir de caractères Unicode.
Java peut afficher n'importe quel caractère à travers son système de fenêtrage AWT, à condition que
Les interfaces java.io.DataInput et java.io.DataOutput contiennent des méthodes appelées 'readUTF', et 'writeUTF' respectivement. Mais notez qu'elles n'utilisent pas UTF-8 ; elles utilisent un encodage UTF-8 modifié : le caractère NUL est encodé dans une séquence de deux octets 0xC0 et 0x80 à la place de 0x00, et un octet 0x00 est ajouté à la fin. Encodées de cette façon, les chaînes peuvent contenir des caractères NUL mais elles doivent néanmoins être préfixées par un champ de taille. Les fonctions C <string.h> comme strlen() et strcpy() peuvent être utilisées pour les manipuler.
Le standard Lisp ordinaire détermine deux types de caractères : 'base-char' et 'character'. C'est à l 'implémentation d'ajouter un support Unicode ou non. Ce langage détermine aussi un mot-clef argument ':external-format' pour 'open' comme place naturelle pour spécifier un jeu de caractères ou un encodage.
Parmi les implémentation gratuites du lisp standard, seul CLISP http://clisp.cons.org/ supporte Unicode. Vous aurez besoin d'une version de CLISP datant de juillet 99 ou plus récente. ftp://clisp.cons.org/pub/lisp/clisp/source/clispsrc.tar.gz Les types "base-char" et "character" sont tous équivalents au 16-bits Unicode. L'encodage utilisé pour le fichier ou l'I/O socket/pipe peut être spécifié par l'argument ':external-format'. Les encodages utilisés pour les opérations d'entrée/sortie sur des ttys et l'encodage par défaut pour les I/O file/socket dépendent des locales.
Parmi les implémentations commerciales du Lisp standard, seule Eclipse
http://www.elwood.com/eclipse/eclipse.htm
supporte Unicode. Voir
http://www.elwood.com/eclipse/char.htm
Le type 'base-char' est équivalent à ISO-8859-1, et le type
'character' contient tous les caractères Unicode.
L'encodage utilisé pour les entrées/sorties sur un fichier peut être
défini à travers une combinaison des arguments de 'open'
':element-type' et :'external.format'.
Limitations : les fonctions
d'attributs de caractères sont dépendantes des locales. Les sources
et les fichiers de sources compilés ne peuvent pas contenir des chaînes
Unicode littérales.
L'implémentation commerciale du Lisp standard Allegro CL ne contient
pas encore de support Unicode, mais Erik Naggum y travaille.
Ada95 a été conçu pour supporter Unicode, et la bibliothèque standard Ada95 contient les types de données spéciaux ISO 10646-1 Wide_Character et Wide_String, ainsi que de nombreuses procédures et fonctions associées. Le compilateur Ada95 GNU (gnat-3.11 ou plus) supporte UTF-8 comme encodage externe des caractères 16 bits. Cela vous autorise à utiliser UTF-8 à la fois dans le code source et dans les entrées/sorties de l'application. Pour l'activer dans l'application, utilisez "WCEM=8" dans la chaîne FORM quand vous ouvrez un fichier, et utilisez l'option du compilateur "-gnatW8" si le code source est UTF-8. Pour plus de détails, voyez les manuels de référence GNAT et Ada95.