Les chaines de caractères
Une chaine de caractères (ou string en anglais) est le terme que l'on utilise pour parler d'un tableau de caractères qui se termine par le caractère nul '\0'.
Quand l'on veut déclarer du texte, il ne serait pas très pratique de devoir créer un tableau contenant chaque caractère un par un.
C'est pour cela qu'il existe un sucre syntaxique en C pour faciliter la déclaration
des chaines de caractères et vous l'avez en réalité déjà utilisé sans le savoir ! Ce sucre syntaxique consiste à entourer le texte
que vous voulez utiliser avec des guillemets doubles "", comme dans la chaine de caractères "Hello World!" par exemple.
Comme vous pouvez le voir, vous avez déjà utilisé cette notation lors de vos appels aux fonctions printf ou scanf.
Pour déclarer une chaine de caractères, vous devez donc déclarer un tableau de caractères mais vous pouvez utiliser le sucre syntaxique pour initialiser ce tableau :
Déclaration d'une chaine de caractères :
char hello[6] = "Hello"; // équivalent à {'H', 'e', 'l', 'l', 'o', '\0'} donc de taille 6Déclaration simplifiée d'une chaine de caractères :
char coucou[] = "Coucou"; // la taille est déduite automatiquement comme pour les tableaux classiques (7 dans ce cas)
Déclaration d'une chaine de caractères dans un tableau plus grand que nécessaire :
char salut[10] = "Salut"; // le reste du tableau est initialisé à '\0' automatiquement
Cela peut être utile si vous prévoyez d'ajouter des caractères à la chaine de caractères plus tard.
Allocation dynamique d'une chaine de caractères de taille
x:char *message = (char *)malloc((x + 1) * sizeof(char));
Le
+ 1est nécessaire pour prendre en compte le caractère nul'\0'à la fin de la chaine de caractères. Il faut faire attention à bien libérer la mémoire allouée avecfree(message);lorsque vous n'en avez plus besoin comme pour les autres tableaux dynamiques. Il est important de noter que dans ce cas, le tableau n'est pas initialisé donc il ne contient pas de'\0'à la fin tant que vous ne l'avez pas fait vous-même.
Itération sur les chaines de caractères
Quand l'on veut manipuler une chaine de caractères, on a besoin de la parcourir comme on le ferait avec un tableau classique.
Cependant, avec un tableau classique, on avait à chaque fois besoin de stocker la taille du tableau dans une variable à part
pour être sûr de ne pas dépasser les limites du tableau lors de l'itération. Avec une chaine de caractères,
on peut se passer de cette variable contenant la taille du tableau car le caractère nul '\0' à la fin de la chaine de caractères
nous indique où nous arrêter.
Voici un exemple d'itération sur une chaine de caractères pour afficher chaque caractère un par un :
Comme vous pouvez le voir, au lieu d'utiliser une condition basée sur une variable contenant la taille du tableau comme i < taille,
on utilise la condition string[i] != '\0' pour s'arrêter dès que l'on rencontre le caractère nul '\0' à la fin de la chaine de caractères.
Fonctions prédéfinies pour les chaines de caractères
Il existe plusieurs fonctions qui sont disponibles dans la bibliothèque standard du C pour manipuler les chaines de caractères.
Dans le module stdio
printf: Affiche une chaine de caractères formatée à l'écran.#include <stdio.h> printf("Hello World!\n"); // Affiche "Hello World!" suivi d'un saut de lignescanf: Lit le premier mot d'une ligne (la première chaine de caractères sans espaces) depuis l'entrée standard.#include <stdio.h> char string[50]; scanf("%s", string); // Lit une chaine de caractères#include <stdio.h> char string[50]; scanf("%49s", string); // Lit une chaine de caractères (max 49 caractères + '\0')#include <stdio.h> char *string; scanf("%ms", &string); // Lit une chaine de caractères allouée dynamiquement (pensez à free(string) quand string n'est plus nécessaire)Dans ce dernier exemple, il faut bien utiliser un
&avant le nom de la variable carscanfva modifier l'adresse stockée dansstringpour qu'elle pointe vers la mémoire allouée dynamiquement.fgets: Lit au maximumn-1caractères d'une ligne depuis un flux d'entrée (comme l'entrée standard).#include <stdio.h> char string[50]; fgets(string, 50, stdin); // Lit une ligne de texte (max 49 caractères + '\0')
Contrairement à
scanf,fgetslit toute la ligne jusqu'au saut de ligne ou jusqu'à atteindre la limite de caractères spécifiée, ce qui permet de lire des chaines de caractères contenant des espaces.
Dans le module string
strlen: Calcule la longueur d'une chaine de caractères (sans compter le caractère nul'\0').#include <string.h> char string[] = "Hello"; int length = strlen(string); // length vaut 5
strcmp: Compare deux chaines de caractères.#include <string.h> char str1[] = "Hello"; char str2[] = "World"; int result = strcmp(str1, str2); // result < 0 car "Hello" est lexicographiquement inférieur à "World"`
strncmp: Compare lesnpremiers caractères de deux chaines de caractères.#include <string.h> char str1[] = "Hello"; char str2[] = "Helium"; int result = strncmp(str1, str2, 3); // result == 0 car les 3 premiers caractères sont identiques
strcpy: Copie une chaine de caractères dans une autre.#include <string.h> char source[] = "Hello"; char destination[6]; strcpy(destination, source); // destination contient maintenant "Hello" (avec le '\0')
strncpy: Copie lesnpremiers caractères d'une chaine de caractères dans une autre.#include <string.h> char source[] = "Hello"; char destination[4]; strncpy(destination, source, 3); // destination contient maintenant "Hel" (pas de '\0' ajouté automatiquement)
#include <string.h> char source[] = "Hello"; char destination[10]; strncpy(destination, source, 10); // destination contient maintenant "Hello" (avec le '\0') mais la fin du tableau n'est pas utilisée
INGInious