Une chaîne de caractères, c'est du texte que l'on peut retenir sous forme de variable en mémoire. On pourrait ainsi stocker le nom de l'utilisateur.
Le type char
Le type char permet de stocker des nombres compris entre -128 et 127.
Le type char est en fait prévu pour stocker une lettre.
Testons :
int main(int argc, char *argv[])
{
char lettre = 'A';
printf("%d\n", lettre);
return 0;
}
Testez avec des minuscules et vous verrez que les valeurs sont différentes. En effet, la lettre'a'n'est pas identique à la lettre'A', l'ordinateur faisant la différence entre les majuscules et les minuscules (on dit qu'il « respecte la casse »).
La plupart des caractères « de base » sont codés entre les nombres 0 et 127. Une table fait la conversion entre les nombres et les lettres : la table ASCII (prononcez « Aski »). Le site AsciiTable.com est célèbre pour proposer cette table mais ce n'est pas le seul, on peut aussi la retrouver sur Wikipédia et bien d'autres sites encore.
Afficher un caractère
int main(int argc, char *argv[])
{
char lettre = 'A';
printf("%c\n", lettre);
return 0;
}
On peut aussi demander à l'utilisateur d'entrer une lettre en utilisant le %c dans un scanf :
int main(int argc, char *argv[])
{
char lettre = 0;
scanf("%c", &lettre);
printf("%c\n", lettre);
return 0;
}
Les chaînes
En C, une chaîne de caractères n'est rien d'autre qu'un tableau de type char.
Si on crée un tableau :
char chaine[5];
et qu'on met dans chaine[0] la lettre'S', danschaine[1] la lettre'a'… on peut ainsi former une chaîne de caractères, c'est-à-dire du texte.
Une chaîne de caractère doit impérativement contenir un caractère spécial à la fin de la chaîne, appelé « caractère de fin de chaîne ». Ce caractère s'écrit'\0'.
Par conséquent, pour stocker le mot « Salut » (qui comprend 5 lettres) en mémoire, il ne faut pas un tableau de 5 char, mais de 6 !
Chaque fois que vous créez une chaîne de caractères, vous allez donc devoir penser à prévoir de la place pour le caractère de fin de chaîne.
Création et initialisation de la chaîne
Si on veut initialiser notre tableau chaine avec le texte « Salut », on peut utiliser la méthode manuelle mais peu efficace :
char chaine[6]; // Tableau de 6 char pour stocker S-a-l-u-t + le \0
chaine[0] = 'S';
chaine[1] = 'a';
chaine[2] = 'l';
chaine[3] = 'u';
chaine[4] = 't';
chaine[5] = '\0';
Cette méthode marche. On peut le vérifier avec un printf.
Pour faire un printf il faut utiliser le symbole %s (scomme string}, qui signifie « chaîne » en anglais). Voici le code complet qui crée une chaîne « Salut » en mémoire et qui l'affiche :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char chaine[6]; // Tableau de 6 char pour stocker S-a-l-u-t + le \0
// Initialisation de la chaîne (on écrit les caractères un à un en mémoire)
chaine[0] = 'S';
chaine[1] = 'a';
chaine[2] = 'l';
chaine[3] = 'u';
chaine[4] = 't';
chaine[5] = '\0';
// Affichage de la chaîne grâce au %s du printf
printf("%s", chaine);
return 0;
}
Vous remarquerez que c'est un peu fatigant et répétitif de devoir écrire les caractères un à un comme on l'a fait dans le tableau chaine. Pour initialiser une chaîne, il existe heureusement une méthode plus simple :
int main(int argc, char *argv[])
{
char chaine[] = "Salut"; // La taille du tableau chaine est automatiquement calculée
printf("%s", chaine);
return 0;
}
Salut
Comme vous le voyez à la première ligne, je crée une variable de typechar[]. J'aurais pu écrire aussi char*, le résultat aurait été le même.
Il y a toutefois un défaut : ça ne marche que pour l'initialisation ! Vous ne pouvez pas écrire plus loin dans le code :
chaine = "Salut";
Cette technique est donc à réserver à l'initialisation. Après cela, il faudra écrire les caractères manuellement un à un en mémoire comme on l'a fait au début.
Récupération d'une chaîne via un scanf
Vous pouvez enregistrer une chaîne entrée par l'utilisateur via un scanf, en utilisant là encore le symbole %s.
Seul problème : vous ne savez pas combien de caractères l'utilisateur va entrer.
Pour ça, il va falloir créer un tableau de char très grand, suffisamment grand pour pouvoir stocker le prénom. On va donc créer unchar[100].
int main(int argc, char *argv[])
{
char prenom[100];
printf("Comment t'appelles-tu ? ");
scanf("%s", prenom);
printf("Salut %s, je suis heureux de te rencontrer !", prenom);
return 0;
}
Fonctions de manipulation des chaînes
Les chaînes de caractères sont, vous vous en doutez, fréquemment utilisées. Tous les mots, tous les textes que vous voyez sur votre écran sont en fait des tableaux de char en mémoire qui fonctionnent comme je viens de vous l'expliquer.
Afin de nous aider un peu à manipuler les chaînes, on nous fournit dans la bibliothèque string.h une pléthore de fonctions dédiées aux calculs sur des chaînes.
#include <string.h>
N'oubliez pas d'inclure cette bibliothèque à chaque fois que vous utilisez des fonctions de manipulation de chaînes.
strlen: calculer la longueur d'une chaîne
strlen est une fonction qui calcule la longueur d'une chaîne de caractères (sans compter le caractère\0).
Vous devez lui envoyer un seul paramètre : votre chaîne de caractères. Cette fonction vous retourne la longueur de la chaîne.
Prototype:
size_t strlen(const char* chaine);
size_t est un type spécial qui signifie que la fonction renvoie un nombre correspondant à une taille. Ce n'est pas un type de base comme int, long ou char, c'est un type « inventé ».
La fonction prend un paramètre de type const char*. Le const (qui signifie constante) fait que la fonction strlen « s'interdit » en quelque sorte de modifier votre chaîne.
Testons la fonction strlen:
int main(int argc, char *argv[])
{
char chaine[] = "Salut";
int longueurChaine = 0;
// On récupère la longueur de la chaîne dans longueurChaine
longueurChaine = strlen(chaine);
// On affiche la longueur de la chaîne
printf("La chaine %s fait %d caracteres de long", chaine, longueurChaine);
return 0;
}
La chaine Salut fait 5 caracteres de long
Cette fonction strlen est d'ailleurs facile à écrire. Il suffit de faire une boucle sur le tableau de char qui s'arrête quand on tombe sur le caractère\0. Un compteur s'incrémente à chaque tour de boucle, et c'est ce compteur que la fonction retourne
int longueurChaine(const char* chaine);
int main(int argc, char *argv[])
{
char chaine[] = "Salut";
int longueur = 0;
longueur = longueurChaine(chaine);
printf("La chaine %s fait %d caracteres de long", chaine, longueur);
return 0;
}
int longueurChaine(const char* chaine)
{
int nombreDeCaracteres = 0;
char caractereActuel = 0;
do
{
caractereActuel = chaine[nombreDeCaracteres];
nombreDeCaracteres++;
}
while(caractereActuel != '\0'); // On boucle tant qu'on n'est pas arrivé à l'\0
nombreDeCaracteres--; // On retire 1 caractère de long pour ne pas compter le caractère \0
return nombreDeCaracteres;
}
La fonction longueurChaine fait une boucle sur le tableau chaine. Elle stocke les caractères un par un dans caractereActuel. Dès que caractereActuel vaut '\0', la boucle s'arrête.
À chaque passage dans la boucle, on ajoute 1 au nombre de caractères qu'on a analysés.
À la fin de la boucle, on retire 1 caractère au nombre total de caractères qu'on a comptés. Cela permet de ne pas compter le caractère \0 dans le lot. Enfin, on retourne nombreDeCaracteres et le tour est joué !
strcpy: copier une chaîne dans une autre
La fonctionstrcpy(comme « string copy ») permet de copier une chaîne à l'intérieur d'une autre.
Son prototype est :
char* strcpy(char* copieDeLaChaine, const char* chaineACopier);
Cette fonction prend deux paramètres :
-
copieDeLaChaine: c'est un pointeur vers unchar*(tableau dechar). C'est dans ce tableau que la chaîne sera copiée ; -
chaineACopier: c'est un pointeur vers un autre tableau dechar. Cette chaîne sera copiée danscopieDeLaChaine.
La fonction renvoie un pointeur surcopieDeLaChaine, ce qui n'est pas très utile. En général, on ne récupère pas ce que cette fonction renvoie. Testons cela :
int main(int argc, char *argv[])
{
/* On crée une chaîne "chaine" qui contient un peu de texte
et une copie (vide) de taille 100 pour être sûr d'avoir la place
pour la copie */
char chaine[] = "Texte", copie[100] = {0};
strcpy(copie, chaine); // On copie "chaine" dans "copie"
// Si tout s'est bien passé, la copie devrait être identique à chaine
printf("chaine vaut : %s\n", chaine);
printf("copie vaut : %s\n", copie);
return 0;
}
chaine vaut : Texte copie vaut : Texte
On voit que chaine vaut « Texte ». Jusque-là, c'est normal.
Par contre, on voit aussi que la variable copie, qui était vide au départ, a été remplie par le contenu de chaine. La chaîne a donc bien été copiée dans copie.
Vérifiez que la chaîne copie est assez grande pour accueillir le contenu de chaine.
Schématiquement, la copie a fonctionné comme sur la fig. suivante.

Chaque caractère de chaine a été placé dans copie.
strcat: concaténer 2 chaînes
Cette fonction ajoute une chaîne à la suite d'une autre. On appelle cela la concaténation.
Supposons que l'on ait les variables suivantes :
-
chaine1 = "Salut " -
chaine2 = "Magoe"
Si je concatène chaine2 dans chaine1, alors chaine1 vaudra "Salut Magoe". Quant à chaine2, elle n'aura pas changé et vaudra donc toujours"Magoe". Seule chaine1 est modifiée.
C'est exactement ce que fait strcat, dont voici le prototype :
char* strcat(char* chaine1, const char* chaine2);
Comme vous pouvez le voir,chaine2 ne peut pas être modifiée car elle est définie comme constante dans le prototype de la fonction.
La fonction retourne un pointeur vers chaine1.
La fonction ajoute à chaine1 le contenu de chaine2. Regardons-y de plus près :
int main(int argc, char *argv[])
{
/* On crée 2 chaînes. chaine1 doit être assez grande pour accueillir
le contenu de chaine2 en plus, sinon risque de plantage */
char chaine1[100] = "Salut ", chaine2[] = "Magoe";
strcat(chaine1, chaine2); // On concatène chaine2 dans chaine1
// Si tout s'est bien passé, chaine1 vaut "Salut Magoe"
printf("chaine1 vaut : %s\n", chaine1);
// chaine2 n'a pas changé :
printf("chaine2 vaut toujours : %s\n", chaine2);
return 0;
}
chaine1 vaut : Salut Magoe chaine2 vaut toujours : Magoe
Vérifiez absolument quechaine1 est assez grande pour qu'on puisse lui ajouter le contenu de chaine2, sinon vous ferez un débordement en mémoire qui peut conduire à un plantage.
La fig. suivante résume le fonctionnement de la concaténation.

Le tableau chaine2 a été ajouté à la suite dechaine1 (qui comprenait une centaine de cases).
Le \0 de chaine1 a été supprimé (en fait, il a été remplacé par le M de Magoe). En effet, il ne faut pas laisser un \0 au milieu de la chaîne, sinon celle-ci aurait été « coupée » au milieu ! On ne met qu'un \0 à la fin de la chaîne, une fois qu'elle est finie.
strcmp: comparer 2 chaînes
strcmp compare 2 chaînes entre elles. Voici son prototype :
int strcmp(const char* chaine1, const char* chaine2);
Les variables chaine1 et chaine2 sont comparées. Comme vous le voyez, aucune d'elles n'est modifiée car elles sont indiquées comme constantes.
Il est important de récupérer ce que la fonction renvoie. En effet, strcmp renvoie :
-
0 si les chaînes sont identiques ;
-
une autre valeur (positive ou négative) si les chaînes sont différentes.
La fonction compare les valeurs de chacun des caractères un à un. Si tous les caractères sont identiques, elle renvoie 0. Si les caractères de la chaine1 sont supérieurs à ceux de la chaine2, la fonction renvoie un nombre positif. Si c'est l'inverse, la fonction renvoie un nombre négatif. Dans la pratique, on se sert surtout de strcmp pour vérifier si 2 chaînes sont identiques ou non.
Voici un code de test :
int main(int argc, char *argv[])
{
char chaine1[] = "Texte de test", chaine2[] = "Texte de test";
if (strcmp(chaine1, chaine2) == 0) // Si chaînes identiques
{
printf("Les chaines sont identiques\n");
}
else
{
printf("Les chaines sont differentes\n");
}
return 0;
}
Les chaînes étant identiques, la fonction strcmp a renvoyé le nombre 0.
strchr: rechercher un caractère
La fonction strchr recherche un caractère dans une chaîne.
Prototype :
char* strchr(const char* chaine, int caractereARechercher);
La fonction prend 2 paramètres :
-
chaine: la chaîne dans laquelle la recherche doit être faite ; -
caractereARechercher: le caractère que l'on doit rechercher dans la chaîne.
Vous remarquerez que caractereARechercher est de type int et non de type char. Ce n'est pas réellement un problème car, au fond, un caractère est et restera toujours un nombre. Néanmoins, on utilise quand même plus souvent un cha rqu'un int pour stocker un caractère en mémoire.
La fonction renvoie un pointeur vers le premier caractère qu'elle a trouvé, c'est-à-dire qu'elle renvoie l'adresse de ce caractère dans la mémoire. Elle renvoie NULL si elle n'a rien trouvé.
Exemple:
int main(int argc, char *argv[])
{
char chaine[] = "Texte de test", *suiteChaine = NULL;
suiteChaine = strchr(chaine, 'd');
if (suiteChaine != NULL) // Si on a trouvé quelque chose
{
printf("Voici la fin de la chaine a partir du premier d : %s", suiteChaine);
}
return 0;
}
Voici la fin de la chaine a partir du premier d : de test
Le schéma de la fig. suivante vous montre où pointe chaque pointeur :

chaine commence au début de la chaine ('T'majuscule), tandis que suiteChaine pointe sur le'd'minuscule.
Variante
Il existe une fonction strrchr strictement identique à strchr, sauf que celle-là renvoie un pointeur vers le dernier caractère qu'elle a trouvé dans la chaîne plutôt que vers le premier.
strpbrk: premier caractère de la liste
Cette fonction ressemble beaucoup à la précédente. Celle-ci recherche un des caractères dans la liste que vous lui donnez sous forme de chaîne, contrairement à strchr qui ne peut rechercher qu'un seul caractère à la fois.
Par exemple, si on forme la chaîne "xds" et qu'on en fait une recherche dans "Texte de test", la fonction renvoie un pointeur vers le premier de ces caractères qu'elle y a trouvé. En l'occurrence, le premier caractère de "xds" qu'elle trouve dans "Texte de test" est lex, donc strpbrk renverra un pointeur sur'x'.
Prototype :
char* strpbrk(const char* chaine, const char* lettresARechercher);
Testons la fonction :
int main(int argc, char *argv[])
{
char *suiteChaine;
// On cherche la première occurrence de x, d ou s dans "Texte de test"
suiteChaine = strpbrk("Texte de test", "xds");
if (suiteChaine != NULL)
{
printf("Voici la fin de la chaine a partir du premier des caracteres trouves : %s", suiteChaine);
}
return 0;
}
Voici la fin de la chaine a partir du premier des caracteres trouves : xte de test
Note :
-
si vous utilisez les guillemets
"", cela signifie chaîne ; -
si vous utilisez les apostrophes
'', cela signifie caractère.
strstr: rechercher une chaîne dans une autre
Cette fonction recherche la première occurrence d'une chaîne dans une autre chaîne.
Son prototype est :
char* strstr(const char* chaine, const char* chaineARechercher);
Le prototype est similaire à strpbrk, mais attention à ne pas confondre : strpbrk recherche UN des caractères, tandis que strstr recherche toute la chaîne.
Exemple :
int main(int argc, char *argv[])
{
char *suiteChaine;
// On cherche la première occurrence de "test" dans "Texte de test" :
suiteChaine = strstr("Texte de test", "test");
if (suiteChaine != NULL)
{
printf("Premiere occurrence de test dans Texte de test : %s\n", suiteChaine);
}
return 0;
}
La fonction strst rrecherche la chaîne "test" dans "Texte de test".
Elle renvoie, comme les autres, un pointeur quand elle a trouvé ce qu'elle cherchait. Elle renvoie NULL si elle n'a rien trouvé.
sprintf: écrire dans une chaîne
Cette fonction se trouve dans stdio.h contrairement aux autres fonctions que nous avons étudiées jusqu'ici, qui étaient dans string.h.
C'est une fonction très pratique pour mettre en forme une chaîne. Petit exemple :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char chaine[100];
int age = 15;
// On écrit "Tu as 15 ans" dans chaine
sprintf(chaine, "Tu as %d ans !", age);
// On affiche chaine pour vérifier qu'elle contient bien cela :
printf("%s", chaine);
return 0;
}
Elle s'utilise de la même manière que printf, mis à part le fait que vous devez lui donner en premier paramètre un pointeur vers la chaîne qui doit recevoir le texte.
Comme d'habitude, vérifiez que votre chaîne est suffisamment grande pour accueillir tout le texte que le sprintf va lui envoyer. Sinon, vous vous exposez à des dépassements de mémoire et donc à un plantage de votre programme.
2017-10-15 16:02:43 / mazoughou@magoe.gn
0 commentaires
Votre impression compte aussi