Les programmes en C manipulent des chaînes probablement plus
que tout autre langage de programmation. Voici un code qui fragmente
une phrase en mots:
#include <stdlib.h>
#include <stdio.h> #include <string.h> int main (int argc, char *argv[]) { int length_of_word; int i; int length_of_sentence; char p[256]; char *q; strcpy (p, "hello there, my name is fred."); length_of_sentence = strlen (p); length_of_word = 0; for (i = 0; i <= length_of_sentence; i++) { if (p[i] == ' ' || i == length_of_sentence) { q = malloc (length_of_word + 1); if (q == 0) { perror ("malloc failed"); abort (); } strncpy (q, p + i - length_of_word, length_of_word); q[length_of_word] = 0; printf ("word: %s\n", q); free (q); length_of_word = 0; } else { length_of_word = length_of_word + 1; } } return 0; } |
strcpy veut dire stringcopy. Cette fonction copie les octets d'un endroit à un autre de manière séquentielle, jusqu'à atteindre l'octet zéro qui signale la fin d'une chaîne. La ligne 13 de ce programme copie le texte dans le tableau de caractères p (character p array) qui est la cible de la fonction strcpy.
strlen signifie stringlength. Cette fonction permet de déterminer la longueur d'une chaîne de caractères, c'est-à-dire le nombre de caractères, y compris les espaces, qui la constituent et ce, jusqu'au caractère zéro de terminaison.
Il est nécessaire d'effectuer une boucle for sur la longueur de la phrase. La variable i sert de compteur indiquant la position courante dans la phrase. La ligne 20 qui commence par if, indique que si nous trouvons un caractère ASCII 32 (c'est-à-dire un espace, noté ' '), nous savons que nous avons atteint la fin d'un mot. Nous savons aussi que la fin de la phrase vaut une fin de mot. Le symbole || désigne un OU logique. Une fois la fin d'un mot atteinte, nous pouvons allouer de la mémoire pour le mot détecté et ensuite copier ce dernier dans l'emplacement mémoire réservé. [NdT: il faut toujours se souvenir d'ajouter une unité à la longueur d'une chaîne (ici d'un mot) pour le zéro de clôture; d'où l'expression malloc (length_of_word + 1).]
La fonction strncpy permet d'effectuer cette dernière opération. Comme pour strcpy, le premier argument est la cible (q) et le second argument est l'objet à copier. Il reste à déterminer la position de début du dernier mot: p + i - length_of_word. [NdT: nous pouvons pratiquer pas-à-pas sur le cas du mot is. Lorsque la lettre ``i'' du mot ``is'' est rencontrée, la valeur du compteur i est 21 puisque le compte a été commencé par i=0. Les deux ``if'' qui suivent l'entrée dans la boucle ``for'' sont passés car, concernant le premier, p[21] vaut 105, selon la table ASCII. Au tour précédent, lorsque la mémoire a été restituée, lentgh_of_word a été ré-initialisé à zéro (ligne 30). A la ligne 32, lentgh_of_word est incrémenté d'une unité. La boucle for continue avec i = 22.La lettre s est rencontrée et, passant les if on arrive à ce que lentgh_of_word devienne = 2. Cependant, au tour suivant, lorsque i = 23, p[23] est un caractère espace. On réserve alors de la mémoire sous forme d'un tableau q (il est à noter que tous les tableaux sont en fait des pointeurs puisque leur nom pointe vers la première adresse hexadécimale du premier octet du tableau). Pour terminer de manière correcte la chaîne de caractère is , on lui adjoint un caractère ``nul'', ce qui est fait en deux temps. A la ligne 21, la mémoire demandée via malloc est de length_of_word + 1 (soit 2+1). A la ligne 27, le dernier élément de q (c'est-à-dire q[lenght_of_word] ou encore q[3]) recevra un zéro de clôture de chaîne. Entre-temps, à la ligne 26, strncpy transfère is dans q. Il s'agit de réaliser une opération arithmétique sur le pointeur p. Celui-ci pointe toujours sur la première adresse hexadécimale du premier octet du tableau p. Lorsqu'on incrémente p d'une unité, le pointe se déplace (comme un curseur) d'une unité car il s'agit d'un type char. Si nous avions eu à faire à un tableau d'entiers, le pointeur eût effectué un déplacement de 4 octets [voir le programme relatif à sizeof dans la section 23.1.5]. Donc, dans la mémoire, le pointeur p s'est déplacé de l'adresse désignant la lettre h à +23 positions (p + i). Là, il pointe vers le caractère ``espace'' suivant le mot ``is''. Ensuite, on le fait se déplacer en arrière de length_of_word (soit 3 octets). Et, dans q , on sauve le mot compris entre ces positions, c'est-à-dire ``is''. Après affichage du mot contenu dans q, la mémoire occupée par q est libérée.
Finalement, à la ligne 27, nous terminons la chaîne par zéro. On peut écrire q, et libérez la mémoire (free) pour recommencer sur le mot suivant.
Pour une liste complète des opérations associées aux chaînes, consultez
string(3).