Skip to main content

Chaines de caractères (et tableaux)

En C il n'y a pas de type String, les chaines de caractères sont simplement des tableaux de caractères. Sauf que puis ce que l'on ne sait pas combien de la longueur du tableau a été replis, donc on met un caractère de fin de chaine à la fin du tableau \0.

char ma_chaine[21] = "Hello World!\n";

2023-09-29_08-38-33_screenshot.png

Il est très important de toujours vérifier l'input des utilisateur·ice·s car si la personne entre quelque chose de plus long que la taille du tableau cela peut être une faille de vulnérabilité (car cela peut mener à un BufferOverflow). C'est notament arrivé au programme sudo sous linux. Si vous voulez en apprendre plus vous pouvez regarder cette vidéo.

Lecture des chaines de caractères

Il existe par exemple gets(), scanf() ou encore fgets() pour prendre un input de l'utilisateur·ice.

Cependant il ne faut pas utiliser gets() car il ne vérifie pas la taille des données (ce qui peut donc mener à un BufferOverflow). Il faut donc toujours utiliser scanf ou getf.

scanf

Voici par exemple comment récupérer les max 20 premiers caractères d'un input (le reste sera ignoré).

scanf("%20[^\n]%*c", ma_chaine);

Pour déconstruire un peu ce qu'il se passe ici :

  • %20 signifique que l'on prends les 20 premiers caractères

  • [^\n] signifie que l'on arrete de prendre des caractères quand l'utilisateur·ice fait ENTER

  • %*c signifie que l'on ignore le dernier caractère (le retour à la ligne \n)

    Autre chose intéressante à noter ici, il n'y a pas de & devant le nom de la fonction contrairement à avant quand on récupérait des caractère ou nombres uniques. Cela est dû au fait que & sert à passer l'addresse d'une variable (le pointeur) et qu'un tableau (comme une chaine de caractère) est déjà une addresse (pointeur).

fgets

fgets fonctionne assez différemment de scanf, voici comment on peut faire quelque chose de similaire à l'exemple précédent en utilisant fgets :

fgets(ma_chaine, 20, stdin);

Attention cependant que fgets compte \n comme un caractère et l'inclus dans le résultat. Donc bien que la syntaxe de fgets soit plus simple, il faut mieux utiliser scanf car elle s'occupe du caractère \n toute seule.

Affichage des chaines de caractères

puts

L'exemple suivant va afficher la chaine de caractère en y ajoutant un retour à la ligne automatiquement à la fin (c'est tout l'interet du puts), c'est un peu comme le System.out.println en Java :

puts(ma_chaine);
fputs

Cet exemple fonctionne de manière similaire du puts sauf qu'il n'ajoute pas de retour à la ligne. C'est un peu comme le System.out.print en Java.

fputs(ma_chaine, stdout);
printf

Printf est surtout intéressant pour formatter l'affichage (c'est l'équivalent du System.out.printf en Java).

printf("%s\n", ma_chaine);

Autres fonctions

Il existe une librarie string en C permettant d'intéragir plus facilement avec les chaines de caractères. Attention cependant, il ne faut pas la confondre avec le type String en Java, car en C "string" n'est pas un type les chaines de caractères sont simplement des tableaux de char

Pour importer la librarie string, il suffit d'ajouter la ligne suivante au dessus du fichier :

#include <string.h>

Maintenant voici une petite listes des fonctions les plus utiles de string :

Fonction Explication
strlen(ma_chaine) Compte le nombre de caractères de la chaine jusqu'au \0
strncmp(chaine1, chaine2, n) Compare les n premiers caractères des chaines. Si les deux sont les même cela signifie que les deux sont identiques
strncpy(dest, source, n) Copie les n premiers caractères de la source vers la destination (le \0 n'est pas ajouté)
sprintf(dest, "%d + %d", 4, 5) Fait comme printf sauf qu'à la place de l'afficher, il le stoque dans une variable. C'est comme le String.format en Java
sscanf(src, "%d + %d", &a, &b) Fait comme le scanf sauf qu'a la place de le demander depuis le stdin (standard input), il va le prendre depuis une chaine de caractère source
memset(src, n, 0) Initialise les n premiers caractères de la chaine src avec le caractère mentioné (ici on remplace tout par \0)
strchr(chaine, car) Recherche la première occurence d'un caractère dans une chaine et retourn eun pointeur vers celle-ci
strstr(chaine, sous-chaine) Recherche la première occurence d'une sous-chaine donnée dans une chaine et retourne un pointeur vers celle-ci.

Exemple de manipulation de tableau/chaines

/* Stoquer une chaine dans un tableau */
char ma_chaine[20+1] = "Hello, World!";

/* Accéder au 5e caractère de la chaine */
printf("Le 5e caractère est %c\n", ma_chaine[4]);

/* Modifier un caractère */
ma_chaine[4] = ' ';

/* On peut aussi mettre le \0 n'importe où pour couper une chaine */
ma_chaine[4] = '\0';
printf("La chaine est maintenant : %s\n", ma_chaine);