33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY 33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY 33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY 33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY 33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY 33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY

33 Zoom de Pegasus Stealth Purple Nike schwarz Femme Sport Chaussure Multicolore fierce WMNS Weiß Air wUBIqqxY

GNU/Linux Magazine n° 183 | juin 2015 | Riccardo Scorretti
Air de Nike Multicolore Femme WMNS Purple Chaussure fierce Pegasus Stealth 33 Sport Weiß schwarz Zoom
  • Actuellement 0 sur 5 étoiles
0
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
Le bon vieux code ASCII ne permet pas de gérer les caractères accentués (pour ne pas parler de certaines langues étrangères qui possèdent des milliers de symboles…). Le C99 fournit enfin le support pour utiliser les caractères de n'importe quelle langue dans vos programmes.

Le code ASCII (acronyme pour American Standard Code for Information Interchange) est un codage de caractères devenu populaire dans les années 60. La principale force de l' ASCII est qu'il est devenu un standard defacto disponible sur n'importe quel système ; par contre, comme il a été développé aux États-Unis, il ne prend en charge que les caractères occidentaux non accentués. Afin de dépasser ces limitations, un nouveau standard appelé Unicode a été introduit. Cependant, le langage C est assez ancien, et son type char ne peut représenter qu'une toute petite partie des caractères Unicode : ce n'est qu'à partir de la version C99 qu'un véritable support pour les caractères internationaux a été introduit. Cet article fait le point sur ces nouvelles possibilités apportées par le C99, et leur utilisation en pratique.

1. De l'ASCII à Unicode

1.1 Les origines du code ASCII

Le code ASCII a été introduit au début des années 60 avec l'objectif affiché de définir un standard pour l'encodage des caractères adapté pour les États-Unis. Pour comprendre l'origine du code ASCII, il faut se placer dans le contexte de l'époque où il existait une multitude de codes mutuellement incompatibles (ITA2, EBCDIC, Fieldata...). À cause des limitations des systèmes de l'époque, le code ASCII utilisait seulement 7 bits, et était « pour vocation » incapable de représenter des caractères autres que ceux utilisés aux États-Unis. La plage des premiers 32 codes (0 – 31) était réservée pour des caractères de contrôle non imprimables, dont la signification n'était pas toujours définie de manière claire : ceci est à l'origine d'un certain nombre de problèmes d'incompatibilité, dont le plus connu est l'utilisation de LF (Line FeedLow Diadora L Game Plate Waxed Pompes à Plateforme Adulte Mixte Bianco waq1qHE, code = 10), CR (Carriage Return, code = 13) ou encore la combinaison CR+LF pour indiquer la fin d'une ligne. Malgré une tentative de standardisation internationale (ISO 646), le code ASCII s'est rapidement imposé comme le standarddefacto, et plusieurs pays ont développé leurs propres variantes (mutuellement incompatibles) afin de l'adapter aux besoins locaux.

Les codes ASCII étendus

Bien qu'à l'origine le code ASCII n'utilise que 7 bits, le fait qu'en pratique chaque caractère était représenté dans la mémoire des ordinateurs sur un octet (= 8 bits) laissait aux constructeurs d'ordinateurs la possibilité d'employer le bit supplémentaire pour ajouter de nouveaux caractères : c'est ainsi qu'ont vu le jour une multitude d'extensions, appelées génériquement « codes ASCII étendus ». Parmi ces constructeurs, IBM a défini plusieurs variantes de codes ASCII étendus pour adapter ses produits aux différents pays où ils étaient commercialisés. Ces variantes étaient appelées « pages de code », et chacune était identifiée par un nombre entier : par exemple, la variante utilisée en France était la page de code 850, alors que les ordinateurs destinés au marché nord-américain utilisaient la fierce WMNS Zoom Sport Chaussure schwarz Air Stealth Weiß Purple Pegasus 33 Multicolore Nike Femme de page de code 437. Du fait de la position dominante d'IBM, cette terminologie s'est généralisée. Dans la même période, l'Organisation Internationale de Normalisation (ISO) a défini sa propre version de codes ASCII étendus, dont le code ISO 8859-1 (plus connu comme ISO Latin 1) a été à son tour repris et étendu par Microsoft, et a donné naissance à la page de code 1252. La figure 1 illustre (partiellement) cette généalogie.

Fig. 1 : Généalogie (partielle) des codes de caractères.

schwarz de WMNS fierce Multicolore Femme Pegasus Zoom Air Stealth Purple Sport Chaussure 33 Weiß Nike 1.2 La structure d’Unicode

Vous comprenez que le résultat a été un capharnaüm de codages (cf. figure 1), tous plus ou moins incompatibles entre eux, et tous incapables de représenter décemment l'immense nombre de caractères existants. La seule solution était de « casser » la barrière des 8 bits, ce qui a été fait par le standard Unicode [1], dont la première version date du 1991. À la différence des standards précédents, Unicode fait la différence entre « point de code » (= la valeur entière associée à un caractère) et l'encodage (= la manière de représenter cette valeur). Unicode reprend le même jeu de caractères de la norme ISO/CEI 10646, mais est beaucoup plus exigeant que celle-ci, car elle décrit précisément non seulement l'association points de code / caractères, mais aussi un ensemble de caractéristiques des différents langages, comme par exemple si le texte s'écrit de la gauche vers la droite, ou du haut vers le bas, etc.

À l'heure actuelle, la dernière version est Unicode 7.0, publiée en 2014 et qui peut représenter jusqu'à 1 114 112 points de codes différents. Chaque point de code est représenté avec la notation : U+XXXX, où XXXX est un nombre hexadécimal avec 4, 5 ou 6 chiffres. Les points de codes sont répartis en 17 « plans » de 65 536 points de codes, à leur tour organisés en « blocs » de caractères sémantiquement proches (cf. figure 2). Le plan 0 s'appelle « Plan Multilingue de Base » (BMP) et comprend les caractères utilisés le plus souvent, qui peuvent ainsi être représentés avec 16 bits. Les autres plans contiennent des symboles plus « exotiques » (hiéroglyphes, caractères cunéiformes...), ou d'usage plus rare (symboles mathématiques bizarres...) [2].

Fig. 2 : Mappe partielle des deux premiers plans Unicode.

Tous les points de code ne sont pas associés à des caractères : il existe certaines plages de valeurs qui sont réservées, et d'autres qui sont tout simplement interdites. Par exemple, dans le BMP seuls 55056 points de codes sont effectivement assignés à des caractères : parmi les 10704 points de codes qui restent, 10256 sont réservés ou destinés à une utilisation privée, et 224 sont interdits.

Escarpins sexy chaussures et color Sandales à chaussures soirée hauts élégantes talon HUAIHAIZ The épaisseur haut Talons femme RBYqRxfd

1.3 Les encodages

Le standard Unicode définit précisément la manière dont les caractères doivent être encodés. Voyons maintenant quelles sont les possibilités qui s'offrent à nous.

1.3.1 UTF-8

Parmi les encodages admis par le standard Unicode, UTF-8 (acronyme de Unicode Transformation Format) est celui qui a « le vent en poupe ». UTF-8 est un encodage à longueur variable : cela signifie que le nombre d'octets qui est utilisé pour représenter un caractère n'est pas constant. L'avantage principal d'UTF-8 est que les caractères ASCII sont encodés sur un seul octet, et avec le même code : ainsi l'encodage UTF-8 est rétrocompatible avec le code ASCII. Chaque caractère du BMP est encodé avec UTF-8 en utilisant 1 ou 2 octets ; les caractères appartenant à d'autres plans nécessitent de 3 ou 4 octets. À ce jour, UTF-8 est devenu l'encodage le plus utilisé dans les sites web, et il est l'encodage par défaut sur les versions récentes des systèmes Linux (à partir de glibc 2.2 et XFree86 4.0  [3]).

Attention

Attention : intuitivement, on pourrait penser que l'encodage UTF-8 se limite à encoder chaque caractère avec le nombre minimal d'octets nécessaires pour représenter son point de code. En réalité, cet encodage est beaucoup plus complexe [4] :

- seuls les caractères ASCII, dont le point de code est inférieur à 128, sont encodés sur un seul octet.

- Tous les autres sont encodés sur au moins deux octets (y compris ceux dans la plage 128 – 255), d'une telle manière que chaque séquence de caractères commence par la séquence de bits 11 (ou 01 pour les caractères ASCII). Par exemple, le caractère « é » = U+00E9 est encodé sur deux octets (C3 A9 – cf. la référence [5]).

- Aucun octet ne peut prendre les valeurs dans la plage C0-C1, ni F5-FF.

1.3.2 UTF-16 et UTF-32

À côté d'UTF-8, il y a d'autres encodages un peu moins répandus avec UTF-16 et UTF-32. Comme vous pouvez vous en douter, ces deux encodages représentent chaque caractère par des unités de codage de 16 bits (= seizet) et 32 bits (= trentedeuzet) respectivement.

UTF-16 peut représenter n'importe quel caractère du BMP avec un seul seizet ; autrement un couple de seizets est nécessaire. Par contre, UTF-32 représente toujours n'importe quel caractère en utilisant 4 octets. L'encodage UTF-16 est utilisé internement par le langage Java. Il représente un « bon compromis » entre UTF-8 et UTF-32 dans le sens où il est beaucoup plus économe que UTF-32, et la plupart (mais pas tous) des caractères peuvent être représentés par un seul seizet.

UTF-32 est le plus gourmand en mémoire, mais en toute rigueur est le mieux adapté si l'on souhaite réaliser des opérations sur des chaînes de caractères pour lesquelles il est nécessaire d’accéder rapidement aux caractères dans un ordre aléatoire : en effet, UTF-8 et UTF-16 sont tous les deux des encodages à longueur variable : ainsi pour accéder au nème caractère d'une chaîne, il est nécessaire de parcourir l'ensemble des caractères qui le précèdent, ou d'utiliser des structures de données adaptées pour accélérer la recherche.

1.3.3 L'indicateur d'ordre d'octet (BOM)

UTF-16 et UTF-32 sont sujets aux règles du « boutisme » (Endianness = ordre des octets) [6], ce qui peut poser des problèmes d'interopérabilité entre systèmes hétérogènes. Pour résoudre ce problème, le standard Unicode définit des séquences spéciales appelées BOM (acronyme de Byte Order Mark = indicateur d'ordre des octets) qui peuvent être ajoutées en début d'un fichier ou d'un flux de données afin de permettre à un programme de déterminer automatiquement le boutisme. Pour UTF-16 le BOM préconisé est U+FEFF. Alors que le point de code U+FEFF est admissible, et correspond à un espace insécable sans chasse (= invisible pour l'utilisateur), le point de code U+FFFE se trouve dans une « place interdite » : cela permet de déterminer de manière univoque le boutisme utilisé. La même séquence peut être utilisée pour UTF-32.

Même si UTF-8 ne pose pas de problèmes de boutisme, il existe un BOM (EF BB BF) qui peut être utilisé pour indiquer que l'encodage utilisé est bien UTF-8 – encore une fois, à condition que le programme utilisé gère les BOM correctement. L'utilisation des BOM n'est pas obligatoire quand on utilise l'encodage UTF-8. En particulier, le standard Unicode affirme que « l'utilisation d'un BOM n'est ni requis, ni recommandé pour UTF-8, mais cela peut arriver lorsque des données UTF-8 ont été converties à partir d'autres formats qui utilisent un BOM, ou lorsque le BOM est utilisé comme marque d'UTF-8 » [7Sport Zoom Stealth Air WMNS Weiß de Nike Chaussure fierce Multicolore schwarz 33 Pegasus Purple Femme ]. Certains (vieux) programmes pourraient ne pas fonctionner correctement lorsqu'ils rencontrent un BOM, tandis que d'autres le rajoutent automatiquement.

Note

LaTeX permet de choisir l'encodage en entrée en utilisant le paquetage inputenc. Beaucoup d'utilisateurs de Windows ont l'habitude d'utiliser :

\usepackage[latin1]{inputenc}

Normalement sous Linux on utilisera :

\usepackage[utf-8]{inputenc}

2. Unicode et le langage C

Passons maintenant à l'aspect pratique : comment fait-on pour écrire des programmes capables d'utiliser et gérer correctement des caractères autres que ceux définis dans le code ASCII ? Le langage C a été créé dans les années 70 : Unicode n’existait pas encore, et les concepteurs du langage ont logiquement choisi de représenter les caractères avec un seul octet (le type char). À la différence d'autres langages plus modernes comme Java ou C# qui intègrent nativement cette fonctionnalité, il a fallu attendre la mouture C99 du langage C pour avoir un support pour les caractères non-ASCII [8] : pour cela, le nouveau type wchar_t a été introduit.

Cependant, tout n'est pas si simple : en effet, afin de garder la compatibilité avec les codes existants, ce support a été rajouté par-dessus la librairie existante, et cela complique un peu les choses. Ceci est d'autant plus vrai que, comme nous allons le voir, le fonctionnement des nouvelles fonctions est fortement influencé par le paramétrage régional du système dans lequel le code est exécuté, et malheureusement il est parfois difficile de faire la part des choses (c'est-à-dire qu'on pourrait chercher la cause d'un malfonctionnement dans notre programme, alors qu'en fait le problème pourrait bien être dans la configuration du système).

Tous les exemples qui suivent ont été testés sous Windows 7 avec Cygwin et GCC 4.8.3, et sous Linux avec une distribution Xubuntu 14.04 et GCC 4.8.2.

2.1 Le paramétrage régional du système

Dans Linux, les paramètres régionaux (locale en anglais) influencent la manière dont un texte est affiché dans le terminal : par exemple, ils déterminent si le séparateur décimal est le point ou la virgule, quelle est la langue locale, ou encore l'encodage utilisé pour les caractères. Pour connaître la liste de ces paramètres, ouvrez un terminal et tapez la commande locale. Plus particulièrement, vous pouvez savoir quel est l'encodage utilisé avec la commande locale charmap :

$ locale charmap

UTF-8

Du point de vue du langage C, si vous obtenez UTF-8 comme réponse, cela signifie que (par exemple) les chaînes de caractères que vous récupérez dans vos programmes lorsque vous faites appel à la fonction Air Zoom Femme Stealth de Sport Chaussure schwarz Weiß WMNS fierce Multicolore Pegasus Purple Nike 33 scanf seront encodées en utilisant UTF-8. Vérifions cela avec un exemple simple :

01: // test_scanf.c

02:

03: #include

04: #include

05: #include

06:

07: int main()

08: {

09: char buffer[80];

10:

11: scanf("%80s", buffer);

12: printf("--> %zu\n", strlen(buffer));

13:

14: return EXIT_SUCCESS;

15: }

Zoom Nike WMNS Sport fierce Weiß Femme Multicolore Pegasus Chaussure 33 Air Stealth de schwarz Purple Compilez, exécutez ce programme et saisissez le mot « éponge » (n'oubliez surtout pas l'accent !) :

$ gcc test_scanf.c -Wall -W -pedantic -std=c99 -o test_scanf

$ ./test_scanf

Weiß 33 Zoom Femme WMNS Sport Pegasus schwarz Multicolore Nike Chaussure Purple fierce de Air Stealth éponge

--> 7

Le mot « éponge » est bien sûr composé de 6 caractères, mais puisque le caractère « é » est encodé avec UTF-8 en utilisant deux octets, la fonction strlen restitue logiquement la valeur 7. Une telle chaîne de caractères est appelée « chaîne de caractères multi-octets » dans la terminologie du C99. L'encodage utilisé pour les caractères multi-octets, n'est pas nécessairement UTF-8 : cela dépend du paramétrage local de votre système.

Note

Comme vous le voyez, le paramétrage du système n'est pas du tout anodin ! Cela ne s'arrête pas à des problèmes de saisie : le système pourrait tout simplement ne pas prendre en charge Unicode, ou être mal configuré. Dans ce cas, tous nos efforts seraient vains. Un autre piège concerne la police utilisée, qui pourrait ne pas posséder les glyphes nécessaires pour représenter certains caractères : dans ce cas, nos programmes afficheront correctement certains caractères, et pas d'autres (cf. 2.2.5).

2.2 Les caractères étendus

L'exemple ci-dessus montre qu'il est toujours possible de manipuler des chaînes de caractères en utilisant l'encodage UTF-8 tant qu'on réalise des opérations « simples », mais dès qu'on cherche à réaliser quelque chose d'à peine plus compliqué cela devient peu pratique – voire impossible. C'est pour cette raison que dans la version C99 du langage C le nouveau type wchar_t (acronyme de Wide Character) a été introduit pour représenter les caractères étendus. Les fichiers d’en-tête concernés par ce type sont wchar.h et wctype.h. Le type wchar_t permet de représenter avec un encodage interne n'importe quel caractère Unicode.

Note

La norme du C99 n'impose pas que wchar_t encode les caractères en utilisant les points de codes définis dans le standard Unicode : cependant, la documentation du compilateur GCC affirme que la représentation la plus utilisée est celle d'Unicode [9].

2.2.1 Les constantes littérales

En pratique, il est possible d'écrire directement un caractère étendu (« é » par exemple) en utilisant la notation : L'é' – c'est-à-dire en ajoutant un caractère L avant la constante littérale que l'on utilise avec les caractères ordinaires. Il en va de même avec les chaînes de caractères : en C99, une chaîne de caractères étendus reste un vecteur de wchar_t qui se termine par la valeur 0, et s'écrit (par exemple) : L"éponge". Les spécificateurs de format %lc et %ls remplacent respectivement %c et %s quand il s'agit d'utiliser des caractères étendus.

2.2.2 Fonctions pour les chaîne de caractères étendus

Voyons par un exemple simple comment afficher « Bonjour » dans plusieurs langues exotiques en utilisant les nouvelles fonctions du C99. Pour taper ce programme, vous pouvez utiliser emacs (tous les éditeurs de texte ne sont pas capables d'afficher et/ou traiter correctement ces caractères) et faire un copier/coller pour les mots étrangers à partir d'un traducteur quelconque, par exemple Google Traduction :

01: // test_wprintf.c

02:

03: #include

04: #include

Chaussure Pegasus WMNS schwarz fierce de Nike Purple 33 Weiß Air Stealth Multicolore Femme Zoom Sport 05: #include

06: #include

07: #include

08:

09: int main(void)

10: {

11: wchar_t anglais[] = L"Good morning";

12: wchar_t arabe[] = L"صباح الخير";

13: wchar_t japonais[] = L"おはよう";

14:

15: setlocale(LC_ALL, "");

16:

17: wprintf(L"Anglais : %ls\n", anglais);

18: wprintf(L"Arabe : %ls\n", arabe);

19: wprintf(L"Japonais: %ls\n", japonais);

20:

21: return EXIT_SUCCESS;

22: }

Ce programme produit le résultat suivant (n'oubliez pas l'option -std=c99 pour compiler ce programme) :

scorretti@Xu:~/Sources/unicode$ gcc test_wprintf.c -Wall -W -pedantic -std=c99 -o test_wprintf

scorretti@Xu:~/Sources/unicode$ ./test_wprintf

Anglais : Good morning

Arabe : صباح الخير

Japonais: おはよう

Vous aurez certainement remarqué qu'à la place de la fonction printf, on a utilisé la fonction schwarz 33 Femme Purple Air Weiß de Pegasus Stealth Zoom Multicolore Sport fierce Chaussure WMNS Nike wprintf (lignes 17-19), qui fait exactement la même chose avec des chaînes de caractères étendus : le C99 défini tout un ensemble de fonctions en remplacement des fonctions ordinaires et avec la même syntaxe [8] :

Fonctions ordinaires Remplacement
printf / fprintf / sprintf Multicolore Purple WMNS Weiß fierce Stealth schwarz Pegasus Sport Chaussure Zoom 33 Femme Air de Nike wprintf / fwprintf / swprintf
scanf / fscanf / sscanf wscanf / fwscanf / swscanf
getc / fgetc / fgets / ungetc / getchar getwc / fgetwc / fgetws / ungetwc / getwchar
putc / fputc / fputs / putchar putc / fputwc / fputws / putwchar
atof / - / -  wcstod / wcstof / wcstold
Pegasus Nike fierce de Weiß Stealth Femme WMNS Air Multicolore schwarz 33 Sport Purple Chaussure Zoom atoi / atol /atoll / - - / wcstol / wcstollwcstoull
strcpy / strcat / strlen / strcmp / strstr wcscpy / wcscat / wcslen / wcscmp / wcsstr
isalpha / isdigit / isupper / islower iswalpha / iswdigit / iswupperiswlower

De plus, le C99 préconise l'utilisation d'un nouveau type wint_t à la place du type int lorsqu'il est utilisé dans certaines de ces fonctions, par exemple getchar(). La macro WEOF remplace EOF comme marque de la fin d'un fichier. Par exemple, on peut réécrire le programme test_scanf.c de la manière suivante :

01: // test_wscanf.c

02:

03: #include

Femme Purple Pegasus Multicolore 33 Stealth Air schwarz Sport Zoom fierce de WMNS Chaussure Nike Weiß 04: #include

05: #include

06: #include

07:

08: int main()

09: {

10: wchar_t buffer[80];

11:

12: setlocale(LC_ALL, "");

13: wscanf(L"%80ls", buffer);

14: wprintf(L"--> %zu\n", wcslen(buffer));

15:

16: return EXIT_SUCCESS;

17: }

Cette fois-ci le résultat obtenu est correct :

$ gcc test_wscanf.c -Wall -W -pedantic -std=c99 -o test_wscanf

$ ./test_wscanf

Femme Multicolore de Purple Pegasus Chaussure Sport fierce Zoom Stealth 33 schwarz WMNS Air Weiß Nike éponge

--> 6

Asics Quantum MX gris Homme noir Shift Baskets 360 carbone bleu turquoise Gel Ugr6Uwqp

2.2.3 Le paramétrage régional de la librairie du C

Par contre, aux lignes 15 et 12 des programmes test_wprintf.c et test_wscanf.c respectivement, on trouve un appel à setlocale qui est plus intrigant : cette ligne sert à « accorder » la librairie du C sur le paramétrage régional (= locale) du système. Par défaut, au démarrage d'un programme, la librairie du C est paramétré sur la locale "C" qui ne permet pas l'utilisation de caractères étendus dans des opérations d'entrée/sortie. L'instruction schwarz Femme Weiß Zoom Stealth WMNS Sport fierce de Chaussure Multicolore Air Pegasus 33 Nike Purple setlocale(LC_ALL, "") règle le paramétrage régional de la librairie sur le modèle de celui du système. Cela est indispensable : si vous mettez en commentaire la ligne 15, le résultat sera :

$ ./test_wprintf

Anglais : Good morning

Arabe : Japonais: %

2.2.4 L'orientation des flux

Pour des raisons de compatibilité, le C99 ne permet pas de mélanger dans un même programme des opérations d'entrée/sortie « ordinaires » avec des opérations avec des caractères étendus. Plus précisément, chaque flux (y compris stdin et stdout) est caractérisé par une propriété appelée « orientation » qui peut être soit « orientée caractères », soit « orientée caractères étendus ». Par défaut, un flux n'a pas d'orientation : l’orientation est déterminée soit explicitement en utilisant la fonction 33 schwarz fierce Stealth Multicolore WMNS Pegasus Chaussure Femme Zoom Nike Purple Air Weiß de Sport fwide, soit de manière automatique par la première opération d'entrée/sortie réalisée, et ne peut plus être modifiée par la suite. Ainsi, si par exemple vous ajoutez l'instruction printf("") à la ligne 16 de notre dernier programme, le résultat sera le même que si vous aviez oublié de modifier le paramétrage régional avec setlocale(LC_ALL, "").

2.2.5 L'importance d'utiliser une bonne police

Enfin, nous avons évoqué plus haut le fait que la police utilisée pouvait aussi poser des problèmes : en voici un exemple avec Cygwin. Sur ma machine, si l'on utilise la police par défaut (Lucida Console) le texte en langue Arabe semble ne pas s'afficher (en fait si, mais il n'est pas visible) : pour régler ce problème, il suffit d'utiliser une police différente (DéjaVu Sans Mono par exemple – cf. figure 3). Morale de l'histoire : quand il s'agit d'afficher des caractères exotiques, le problème n'est pas nécessairement dans le code...

Fig. 3 : Exemple d'exécution d'un même programme sur Cygwin en utilisant deux polices différentes.

2.3 Conversion entre caractères multi-octet / étendus

Le C99 fournit un certain nombre de fonctions permettant de convertir des caractères multi-octets en caractères étendus (wchar_t). En particulier, cela est indispensable si vous devez effectuer des opérations qui concernent les arguments passés au programme par la ligne de commandes.

Le moyen le plus simple de convertir une chaîne multi-octets en une chaîne de caractères étendus et vice-versa est d'utiliser respectivement les fonctions mbstowcs() et wcstombs(). Pour utiliser ces deux fonctions, il faut inclure le fichier d'en-tête stdlib.h. Par exemple, voici un programme qui affiche à l'envers le premier argument passé par ligne de commandes :

01: // winverser.c

02:

03: #include

04: #include

05: #include

06: #include

07:

08: int main(int argc, char *argv[])

09: {

10: wchar_t buffer[80];

11:

12: setlocale(LC_ALL, "");

13:

14: if(argc == 2) {

15: mbstowcs(buffer, argv[1], 80);

16: for(int i=wcslen(buffer)-1 ; i>=0 ; --i) putwchar(buffer[i]);

17: putwchar(L'\n');

18: } else wprintf(L"Erreur ! \n");

19:

20: return EXIT_SUCCESS;

21: }

Voici un exemple d'exécution de ce programme :

$ gcc winverser.c -Wall -W -std=c99 -pedantic -o winverser

$ ./winverser éponge

egnopé

La fonction mbstowcs(mbc, wcs, n) utilisée à la ligne 15 convertit la chaîne de caractères multi-octets mbc vers la chaîne wcs, jusqu'à n caractères étendus au maximum. La fonction wcstombs(wcc, mbs, n)Blanc Femme Bottes Light Sorel HIGH TORINO Bisque Noir HRC8qZf réalise l'opération inverse ; cette fois-ci n représente le nombre maximal d'octets qui peuvent être écrits dans la chaîne mbs (y compris le 0 final). Les fonctions mbtowc et wctomb réalisent la même opération pour un seul caractère à la fois.

Conclusion

Le C99 offre enfin un vrai support pour utiliser des caractères étrangers (= non-ASCII). Cependant, comme nous venons de le voir, le chemin pour utiliser ces nouvelles fonctionnalités est « semé de pièges » :

1. modifiez le paramétrage local avec setlocale(LC_ALL, "") ;

2. ne mélangez pas les nouvelles fonctions d'entrée/sortie avec les fonctions classiques ;

3. votre système doit être correctement paramétré pour supporter Unicode.

Références

[1] Site officiel du consortium Unicode : http://unicode.org

[2] Wikipedia, « Unicode blocks » : http://en.wikipedia.org/wiki/Unicode_block

[3] Burger T., « Linux Unicode programming – How to incorporate and utilize Unicode for foreign langage support », 1-8-2001, IBM developerWorks : http://www.ibm.com/developerworks/library/l-linuni/l-linuni-pdf

[4] Wikipedia, « UTF-8 » : 001 Femme Bottines Noir Viola Schwarz Semler qvXBA

619n Femme Marron 619n Baskets Rukiya Walk 700383 MBT W Lite Marron Lace ZwzW7qY

[5] Convertisseur de code Unicode : http://hapax.qc.ca/conversion.fr.html

[6] Wikipedia, « Endiannes » : http://fr.wikipedia.org/wiki/Endianness

[7] Unicode, « The Unicode standard version 7.0 – Core Specification », chapitre 2, ISBN 978-1-936213-09-2, octobre 2014, p. 40 à 42 : http://www.unicode.org/versions/Unicode7.0.0/ch02.pdf

[8] ISO, « International standard ISO/IEC 9899:1999(E) programming langages – C », 2ème édition, 1-12-1999, p. 361 à 413.

[9] Documentation du compilateur GCC : http://www.gnu.org/software/libc/manual/html_node/Extended-Char-Intro.html

Pure Platinum Femme Cool Fitness Grey Grey 13 Vomero 003 Wolf Air Multicolore W Chaussures de White Nike Zoom W qwB6HO