CPGE Oujda                                                                                                                                            Sup

Les chaînes de caractères

 

Par définition, une chaîne de caractères, ou tout simplement : chaîne, est une suite finie de caractères. Par exemple, "Bonjour", "3000", "Salut !", "EN 4", ... sont des chaînes de caractères. En langage C, une constante de type chaîne de caractères s'écrit entre double quottes, exactement comme dans les exemples donnés ci-dessus.

Longueur d'une chaîne

La longueur d'une chaîne est le nombre de caractères qu'elle comporte. Par exemple, la chaîne "Bonjour" comporte 7 caractères ('B', 'o', 'n', 'j', 'o', 'u' et 'r'). Sa longueur est donc 7. En langage C, la fonction strlen, déclarée dans le fichier string.h, permet d'obtenir la longueur d'une chaîne passée en argument. Ainsi, strlen("Bonjour") vaut 7.

Représentation des chaînes de caractères en langage C

Comme nous l'avons déjà mentionné plus haut, les constantes de type chaîne de caractères s'écrit en langage C entre double quottes. En fait, le langage C ne dispose pas vraiment de type chaîne de caractères. Une chaîne est tout simplement représentée à l'aide d'un tableau de caractères.

Cependant, les fonctions manipulant des chaînes doivent être capables de détecter la fin d'une chaîne donnée. Autrement dit, toute chaîne de caractères doit se terminer par un caractère indiquant la fin de la chaîne. Ce caractère est le caractère '\0' et est appelé le caractère nul ou encore caractère de fin de chaîne. Son code ASCII est 0. Ainsi la chaîne "Bonjour" est en fait un tableau de caractères dont les éléments sont 'B', 'o', 'n', 'j', 'o', 'u', 'r', '\0', autrement dit un tableau de 8 caractères et on a donc "Bonjour"[0] = 'B', "Bonjour"[1] = 'o', "Bonjour"[2] = 'n', ... "Bonjour"[7] = '\0'. Toutefois, comme il s'agit d'une constante (constante chaîne de caractères), le contenu de la mémoire allouée pour la chaîne "Bonjour" ne peut être modifié.
Les fonctions de manipulation de chaîne de la bibliothèque standard du langage C sont principalement déclarées dans le fichier string.h. Voici un exemple d'utilisation d'une de ces fonctions.

#include <stdio.h>
#include <string.h>
 
int main()
{    char t[50];
    
    strcpy(t, "Hello, world!");
    printf("%s\n", t);
    
    return 0;
}

Dans cet exemple, la chaîne t ne peut contenir tout au plus que 50 caractères, caractère de fin de chaîne inclus. Autrement dit t ne peut que contenir 49 caractères « normaux » car il faut toujours réserver une place pour le caractère de fin de chaîne : '\0'. On peut aussi bien sûr initialiser une chaîne au moment de sa déclaration, par exemple :

char s[50] = "Bonjour";

Qui est strictement équivalente à :

char s[50] = { 'B', 'o', 'n', 'j', 'o', 'u', 'r', '\0'};

Puisque, vu d'un pointeur, la valeur d'une expression littérale de type chaîne n'est autre que l'adresse de son premier élément, on peut utiliser un simple pointeur pour manipuler une chaîne. Par exemple :

char * p = "Bonjour";

Dans ce cas, p pointe sur le premier élément de la chaîne "Bonjour". Or, comme nous l'avons déjà dit plus haut, la mémoire allouée pour la chaîne "Bonjour" est en lecture seule donc on ne peut pas écrire par exemple :

p[2] = '*'; /* Interdit */

Avec un tableau, ce n'est pas l'adresse en mémoire de la chaîne qui est stockée, mais les caractères de la chaîne, copiés caractère par caractère. La mémoire utilisée par le tableau étant indépendante de celle utilisée par la chaîne source, on peut faire ce qu'on veut de notre tableau. La fonction strcpy permet de copier une chaîne vers un autre emplacement mémoire.
Le paragraphe suivant discute des fonctions de manipulation de chaînes en langage C.

 

Les fonctions de manipulation de chaîne

strcpy, strncpy
#include <stdio.h>
#include <string.h>
 
int main()
{
    char t1[50], t2[50];
    
    strcpy(t1, "Hello, world!");
    strcpy(t2, "*************");
    strncpy(t1, t2, 3);
    printf("%s\n", t1);
    
    return 0;
}

Attention ! Si t1 n'est pas assez grand pour pouvoir contenir la chaîne à copier, vous aurez un débordement de tampon (buffer overflow). Un tampon (ou buffer) est tout simplement une zone de la mémoire utilisée par un programme pour stocker temporairement des données. Par exemple, t1 est un buffer de 50 octets. Il est donc de la responsabilité du programmeur de ne pas lui passer n'importe quoi ! En effet en C, le compilateur suppose que le programmeur sait ce qu'il fait !
La fonction strncpy s'utilise de la même manière que strcpy. Le troisième argument indique le nombre de caractères à copier. Aucun caractère de fin de chaîne n'est automatiquement ajouté.

strcat, strncat
#include <stdio.h>
#include <string.h>
 
int main()
{
    char t[50];
    
    strcpy(t, "Hello, world");
    strcat(t, " from");
    strcat(t, " strcpy");
    strcat(t, " and strcat");
    printf("%s\n", t);
    
    return 0;
}


strlen

Retourne le nombre de caractères d'une chaîne.

strcmp, strncmp

On n'utilise pas l'opérateur == pour comparer des chaînes car ce n'est pas les adresses qu'on veut comparer mais le contenu mémoire. La fonction strcmp compare deux chaînes de caractères et retourne :

Ainsi, à titre d'exemple, dans l'expression

strcmp("clandestin", "clavier")

La fonction retourne un nombre négatif car, 'n' étant plus petit que 'v' (dans le jeu de caractères ASCII, ça n'a rien à voir avec le langage C), "clandestin" est plus petit que "clavier".

Implémentation de quelques fonctions de manipulation de chaîne

Nous allons donc implémenter deux fonctions de manipulation de chaîne à savoir str_len et str_cpy, qui s'utiliseront de la même manière que leurs bessons strlen et strcpy.

size_t str_len(char * t)
{
    size_t len;
    
    for(len = 0; t[len] != '\0'; len++)
        /* On ne fait rien, on laisse seulement boucler */ ;
    
    return len;
}

 

char * str_cpy(char * dest, char * source)
{
    int i;
    
    for(i = 0; source[i] != '\0'; i++)
        dest[i] = source[i];
    
    dest[i] = '\0';
    
    return dest;
}

Remarquez bien la manière dont nous avons implémenté la fonction str_cpy. Vous vous attendiez peut-être à ce que cette fonction retourne void et non un char *. Et bien non ! De nombreuses fonctions de la bibliothèque standard utilisent également cette « convention », ce qui permet d'écrire du code du genre :

char s[50] = "Bonjour";
printf("%s\n", strcat(s, " tout le monde !"));