Langage C & C++ Chap 8
Langage C & C++ Chap 8
Langage C & C++ Chap 8
Eléments de contenu
• La convention de représentation de chaînes de caractères en C
• Les entrées sorties de chaînes
• Les fonctions de concaténation de chaînes
• Les fonctions de comparaison de chaînes
• Les fonctions de copie de chaînes
• Les fonctions de recherche dans une chaîne
• Les fonctions de conversion
Introduction
Certains langages (tels que le Basic ou le Turbo Pascal) disposent d’un véritable “type chaînes’’. Les
variables d’un tel type sont destinées à recevoir des suites de caractères qui peuvent évoluer, à la fois
en contenue et en longueur, au fil du déroulement du programme. Elles peuvent être manipulées d’une
manière globale.
D’autres langages (tels que Fortran ou le Pascal standard) ne dispose pas d’un tel type chaîne. Pour
traiter de telles informations, il est nécessaire de travailler sur des tableaux de caractères, dont la taille est
nécessairement fixe (ce qui impose une longueur maximum aux chaînes et entraîne donc une perte de l
‘emplacement mémoire).
En langage C, il l’existe pas de véritable type chaîne, dans la mesure où on ne peut pas déclarer
des variables de ce type. Par contre, il existe une convention de représentation des chaînes.
Celle-ci est utilisée à la fois :
• par le compilateur pour représenter les constantes chaînes (notées entre double quotes),
• par un certain nombre de fonctions qui permettent de réaliser :
- les lectures ou écritures de chaînes,
- les traitements classiques tels que la concaténation, recopie, comparaison, extraction de sous-
chaîne, conversions, ...
Mais, comme il n’existe pas de type chaîne, il faudra prévoir un emplacement pour accueillir ces
informations. Un tableau de caractères pourra faire l’affaire c’est ce que nous allons utiliser dans ce
chapitre. Mais nous verrons plus tard comment créer dynamiquement des emplacements mémoires,
lesquels seront alors repérés par des pointeurs.
b o n j o u r \0
adr
VIII.1.b. Initialisation de tableaux de caractères
Comme on l’a dit, nous sommes souvent amenés, en C, a placer des chaînes dans des tableaux de
caractères.
Mais, si on déclare, par exemple : char ch[20] ;
On ne pourra pas transférer une chaîne constante dans ch en écrivant une affectation du genre :
ch =” bonjour”;
En effet, ch est une constante pointeur et non une ivalue ; il n’est donc pas possible de lui attribuer
une valeur.
Par contre, C nous autorise a initialiser notre tableau de caractères à l’aide dune chaîne constante.
Ainsi, on pourra écrire : char ch[20] =’’bonjour’’
Ceci sera parfaitement équivalent à une initialisation de ch réalisée par une énumération de
caractères (sans oublier le code 0 noté \0) : char ch[20]={‘b’,’o’ ,’n’,’j’,’o’,’u’,’r’,’\0’} ;
VIII.1.c. Initialisation de tableaux de pointeurs sur des chaînes
Nous avons vu qu’une constante chaîne de caractères était traduite par le compilateur en une
adresse que l’on pouvait, par exemple, affecter à un pointeur sur une chaîne. Cela peut se
généraliser à un tableau de pointeurs, comme dans :
char * jour [7] ={ “lundi”, “mardi”, “mercredi “, “jeudi”, ‘‘Vendredi’’, “ samedi’’, “ dimanche’’} ;
Cette déclaration réalise donc, à la fois
- la création des 7 constantes chaînes correspondant aux 7 jours de la semaine,
- l’initialisation du tableau jour avec les 7 adresses de ces 7 chaînes.
Voici un exemple utilisation cette déclaration :
main()
{
char *jour [7] = { “lundi “, “mardi “, “mercredi “, “jeudi, ‘‘vendredi “, “samedi “, ‘‘dimanche ‘‘) ;
int i ;
printf(’’donnez un entier 1 et 7 :’’)
scanf(”%d’’, &i) ;
printf (“le jour n° %d de la semaine est %s”, i, jour[i-1]) ;
}
donnez un entier 1 et 7 :3 le jour n° 3 de la semaine est mercredi
VIII.2. LES ENTREES-SORTIE DE CHAINES
Le langage C offre plusieurs possibilités de lecture ou d’écriture de chaînes
• l’utilisation du code format %s dans les fonctions printf et scanf ou (esscanf)
• les fonctions spécifiques de lecture (gets) ou d’affichage (puts) d’une chaîne (une seule à la fois),
• la fonction de lecture directe au clavier (cgets) qui présente l’avantage d’autoriser un contrôle de la
taille de la chaîne lue et, permet de vous protéger contre un éventuel risque de débordement.
Ici nous nous limitons aux entrées-sorties conversationnelles les autres possibilités seront examinées lors de
l’étude des fichiers.
VIII.2.a. Les fonctions gets, puts et le code format %s
Examinons cet exemple de programme :
main()
{
Quelle est votre ville : Tunis
char nom [ 20], prenom[20], ville[25] ;
printf(’’quelle est votre ville :’’) ; Donnez votre nom et votre prénom : Foulen ben Foulen
gets(ville) ; Bonjour cher Foulen ben Foulen qui habite à Tunis
printf(’’donnez votre nom et votre prénom :’’) ;
scanf(‘’%s%s’’, nom ,prenom) ;
printf(‘’bonjour cher %s %s qui habite à ‘’,nom ,prenom) ;
puts(ville) ;
}
Les fonctions printf et scanf permettent de lire et d’afficher simultanément plusieurs informations le
type quelconque. Par contre gets et puts ne traitent qu’une chaîne à la fois.
De plus, les délimitations de la chaîne lue ne s’effectuent pas de la même façon avec scanf et gets. Plus
précisément :
• avec le code %s de scanf les délimiteurs sont classiquement l’espace, la tabulation ou la fin de ligne.
Ceci interdit la lecture d’une chaîne contenant des espaces.
• avec gets, seule la fin de ligne sert de délimiteur.
Dans tous les cas, on remarque que la lecture de n caractères implique le stockage en mémoire de n+1
caractères car le caractère de fin de chaîne (\0) est généré automatiquement par les fonctions de
lecture.
Ainsi, dans notre précédent programme, il n’est pas souhaitable que le nom fourni en donnée contienne
plus de 19 caractères.
Remarques :
1) Dans les appels des fonctions scanf et puts, les identificateurs de tableaux comme nom, prénom ou
ville ne doivent pas être précédés de l’opérateur & puisqu’ils représentent déjà des adresse.
2) La fonction gets fournit en résultat, soit un pointeur sur la chaîne lue, soit un pointeur nul on cas
d’anomalie.
3) La fonction puts réalise un changement de ligne en fin de l’affichage de la chaîne, ce qui n’est pas
le cas de la fonction printf avec le code format %s.
VIII.2.b. Les fonctions cgets et sscanf
Le problème de risque de débordement de l’espace alloué à une chaîne lue en donnée peut être
résolue par l’utilisation de la fonction cgets à la place de gets. Celle-ci permet d’imposer un nombre
maximum de caractères à lire.
Voici un exemple qui lit une chaîne comportant au maximum 27 caractères (28 avec le caractère
nul de fin de chaîne).
# include <stdio.h>
main()
{
char texte[30];
printf(‘’donnez un texte : ‘’) ;
texte [0]=28 ;
cgets(texte) ;
printf(‘’vous avez fini %d caractères \n ‘’,texte[1]) ;
puts(&texte[2]= ;
}
Donnez un texte : bonjour // Vous avez fini 7caractères // bonjour
Donnez un texte : abcdefghijklmnopqrstuvwxyza
Vous avez fourni 27 caractères abcdefghijklmnopqrstuvwxyza
En fait cgets utilise les deux premiers caractères de la “zone” dont on lui fournit l’adresse pour gérer sa
lecture :
• le premier octet doit être initialisé par le programme au nombre maximum de caractères que l’on
souhaite ranger en mémoire, y compris le caractère nul de fin
• le second octet sera renseigné par cgets à la fin de l’opération pour indiquer le nombre de
caractères effectivement lus.
Cette fonction ne lira pas plus de caractères que prévu. Si l’utilisateur cherche à en fournir
davantage, il en sera informé par l’émission d’un bip sonore. Notez que, dans tous les cas, il doit
valider sa réponse par la touche return.
Nous avons vu les problèmes posés par scanf en cas de réponse incorrecte de la part de l’utilisateur.
Il est possible de régler la plupart de ces problèmes on travaillant en deux temps :
• lecture d’une chaîne de caractères par cgets
• vérification du format de manière comparable à ce que ferait scanf.
Voici un exemple de programme permettant de questionner l’utilisateur jusqu’à ce qu’il ait fournit
une réponse satisfaisante :
# define LG 80
# define LG3 LG+3
#include <stdio.h>
main()
{
int n, compte;
char c;
char tampon[LG3] ;
tampon[0]=LG+1;
do
{
printf(“Donnez un entier et un caractère :’’) ;
cgets tampon() -
compte = sscanf(&tampon[2], ”%d %c”, &n, &c,);
} while (compte <2) ;
printf (“merci pour, %d %c “, n, c) ;
}
Donnez un enter et un caractère : bof
Donnez un entier et un caractère : a 125
Donnez un entier et un caractère : 12 bonjour
Merci pour 12 b
VIII.3. LES PONCTIONS DE CONCATENATION DE CHAINES
La concaténation est la juxtaposition de chaînes afin d’en former une seule. Elle est réalisée en C à
l’aide de l ‘une des deux fonctions strcat et strncat (dont les prototypes figurent dans string. h)
VIII.3.a. La fonction strcat
Examinons cet exemple :
#include <string.h>
main()
{
char ch1[50]=’’bonjour’’ ; //avant bonjour
char *ch2=’’monsieur”; //après : bonjour monsieur:
printf (“avant: %s\n “, ch1);
strcat(ch 1, ch2);
printf (“après: %s\n’’,ch 1);
}
Il faut noter la différence entre les deux déclarations (avec initialisation) de chacune des deux chaînes
ch1 et ch2. La première permet de réserver un emplacement plus grand que la constante chaîne
qu’y trouve place initialement.
L’appel de strcat se présente ainsi : strat (destination, source)
Cette fonction recopie la seconde chaîne source à la suite de a première destination, après en avoir
effacé le caractère de fin.
Remarque :
1) Aucun contrôle de longueur n’est réalisé par cette fonction ; il est nécessaire que emplacement
réservé pour la première chaîne soit suffisant pour y recevoir la partie à lui concaténer.
2) Après exécution de srtcat, la première chaîne n’existe plus en tant que telle.
3) strcat fournit un résultat
- l’adresse de la chaîne correspondant à la concaténation des deux chaînes fournies en
argument, lorsque l’opération s’est bien déroulée. Ce n’est rien d’autre que l’adresse de ch1.
Le pointeur nul lorsque l’opération s’est mal déroulée.