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";
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.
TODO pas d'utf-8
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
.
TODO 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);