En langage C, une chaîne de caractères est représentée par un tableau de caractères, sachant qu'un caractère est représenté par un octet. La fin de la chaîne est marquée par le caractère de fin de chaîne '\0', soit la valeur 0 codée sur 8 bits.
Les caractères sont entourés de guillemets simples (en anglais simple quotes) alors que les chaînes sont entourées de guillemets doubles (double quotes).
Certains caractères sont dits spéciaux comme la fin de ligne ou la tabulation et sont représentés par un caractère anti-slash suivi d'une lettre ou d'un chiffre :
La chaine "bonjour" est donc modélisée en mémoire par $8$ octets :
Le premier caractère 'b' se trouve à l'indice $0$ du tableau, et le dernier, '\0', se trouve à l'indice $7$.
Voici un petit programme qui montre comment manipuler les chaînes en C :
Le résultat au niveau du terminal donne :
bon jour
longueur de la chaine: 9
premier caractère: 98 b
dernier caractère: 10
Afin de faciliter l'utilisation des chaînes en C++, la classe string a été introduite.
Elle dispose de méthodes comme size() qui retourne la longueur de la chaîne. On a également introduit la concaténation de chaînes grâce à la redéfinition de l'opérateur +.
Voici le même programme que précédemment mais en C++ avec la concaténation de chaînes :
L'ASCII pour American Standard Code for Information Interchange est une norme de codage des caractères apparue dans les années 1960. Elle est utilisée pour représenter les chaînes de caractères.
La première norme est l'ASCII 7 bits qui permet de représenter 128 caractères date du début des années 1960.
L'ASCII a ensuite été étendu à 8 bits, soit 256 caractères, pour deux raisons :
On trouvera une description plus détaillée sur cette page Wikipedia.
On notera que la distance entre les majuscules et minuscules est de 32. Ainsi pour transformer 'A' en 'a', il suffit d'ajouter 32 au code ASCII de 'A'. Du point de vue du binaire, il suffit de positionner le bit 5 à 1, puisque $2^5 = 32$.
Voici un programme C++ qui transforme une chaîne en majuscule et minuscule.
Le problème de l'ASCII est qu'il ne permet de coder que 256 caractères différents ce qui est insuffisant au regard de toutes les langues qui existent ainsi que des symboles (mathématiques, physique, chimie) que l'on peut utiliser dans l'écriture courante.
Le standard Unicode dans sa version 13 permet de coder $143\_859$ caractères ce qui couvre la presque totalité des caractères connus.
On pourra trouver l'équivalence des premiers caractères sur cette page.
L'encodage par octet, UTF-8 Universal Character Set (Transformation Format), a été conçu pour coder des chaînes à la manière de ce que l'on peut faire avec l'ASCII et est très utilisé par le protocole HTML et les éditeurs de texte. Il existe trois codages UTF dits UTF-8, 16 ou 32.
Le standard Unicode définit des ensembles de caractères et chaque caractère est identifié par son point de code qui est en fait un indice entier. Par exemple le symbole € a pour point de code la valeur 8364 soit U+20AC en hexadécimal dans le standard Unicode.
L'UTF permet de transformer le point de code des caractères Unicode en une série d'octets.
L'intérêt majeur de l'UTF-8 est qu'il est rétro-compatible avec l'ASCII 7 bits :
En UTF-32 chaque caractère est codé par une valeur 32 bits ce qui prend plus de place que l'UTF-8. Comme on peut le voir ci-dessous.
Imaginons que notre fichier contienne 5 lettres puis un passage à la ligne (↵) :
aéïou↵
Voici les différents codages obtenus grâce aux utilitaires linux iconv, konwert et hexdump pour l'affichage. Il est à noter que iconv ne parvient pas à réaliser la transformation vers l'ASCII semble t-il, je l'ai donc réalisée moi-même.
Les codages sont donnés en octets en base 16 :
ASCII
00000000 61 82 8b 6f 75 0a |aeiou.|
00000006
UNICODE
00000000 ff fe |61 00| e9 00| ef 00| 6f 00| 75 00| 0a 00 |..a.....o.u...|
0000000e
UTF8
00000000 61| c3 a9| c3 af| 6f| 75| 0a |a....ou.|
00000008
UTF-16
00000000 ff fe| 61 00| e9 00| ef 00| 6f 00| 75 00| 0a 00 |..a.....o.u...|
0000000e
UTF-32
00000000 ff fe 00 00| 61 00 00 00| e9 00 00 00| ef 00 00 00| |....a...........|
00000010 6f 00 00 00| 75 00 00 00| 0a 00 00 00| |o...u.......|
0000001c
La suite de valeurs FF FE en UTF-16 bits et FF FE 00 00 en UTF-32 indique l'ordre de lecture des caractères, ici cela signifie qu'il faut commencer par la première valeur trouvée.
Dans le cas de l'UTF-32, la séquence d'octets 61 00 00 00 doit donc être considérée comme la valeur hexadécimale $00\_00\_00\_61_{16} = 97_{10} = $ 'a'.
Exercice 3.1
Coder la chaîne suivante "29, éÄ!"
Exercice 3.2
Chiffrer la chaine "a l'aide" en remplaçant chaque lettre par la suivante et les signes de ponctuation ou les espaces par un '.'. Si on doit chiffrer la lettre 'z', on recommence à partir de 'a'. Toute les lettres doivent apparaître sans accent.
Exercice 3.3
Déchiffrer la chaine "KPHQTOG.OC.VKSWG" en remplaçant chaque lettre par la lettre qui se trouve à deux positions précédentes. Dans ce cas 'B' se transforme en 'Z' et 'A' en 'Y'.
Exercice 3.4
Combien d'octets sont nécessaires pour coder une chaîne UTF-8 contenant :
Exercice 3.5
Combien d'octets sont nécessaires pour coder une chaîne UTF-32 contenant :