Vous êtes sur la page 1sur 38

Programmation II

Module: M6 - LFSMI - S4

Prof. R. HANNANE
r.hannane@uca.ma

Faculté des Sciences Semlalia, Marrakech


Université Cadi Ayyad

Prof. R. HANNANE (FSSM) Programmation II 1 / 38


Les chaı̂nes de caractères

Les chaı̂nes de caractères

Prof. R. HANNANE (FSSM) Programmation II 2 / 38


Les chaı̂nes de caractères

Introduction
Récapitulatif sur le type char

Le type char permet de stocker des nombres allant de -128 à


127, unsigned char des nombres de 0 à 255

Une variable de type char est destinées à recevoir un


caractère et ceci entre 0 0
char reponse = ’O ’;

Le langage C permet de faire très facilement la


traduction nombre <=> caractère

Prof. R. HANNANE (FSSM) Programmation II 3 / 38


Les chaı̂nes de caractères

Introduction
Récapitulatif sur le type char
La table ASCII fait la conversion entre les nombres et les
lettres

Prof. R. HANNANE (FSSM) Programmation II 4 / 38


Les chaı̂nes de caractères

Introduction
Récapitulatif sur le type char

Pour afficher ou saisir un caractère, on doit utiliser le symbole %c


Exemple 1:
int main ()
{
char reponse ;
printf ( " Voulez - vous continuer ? ( O / N ) \ n " );
scanf ( " % c " ,& reponse );
printf ( " Votre reponse est % c \ n " , reponse );
printf ( " Votre reponse est % d \ n " , reponse );
return 0;
}
/* Affichage :
Voulez - vous continuer ? ( O / N )
O
Votre reponse est O
Votre reponse est 79
*/

Prof. R. HANNANE (FSSM) Programmation II 5 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Introduction

Une variable de type chaı̂ne de caractère est destinées à


recevoir des suites de caractères
" Ceci est une cha ı
^ ne de caract è re "

En C, il n’existe pas à proprement parler de type chaı̂ne


de caractère

⇒ Ceci fait que le langage n’a pas d’opérateur ou de


mot-clefs réservés pour le traitement de celles-ci

Prof. R. HANNANE (FSSM) Programmation II 6 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Introduction

En revanche, il existe une convention de représentation des


chaı̂nes. Celle-ci est utilisée à la fois par :

I Le compilateur pour représenter les chaı̂nes constantes


(notées entre guillemets ” ”)

I Un certain nombre de fonctions qui permettent de réaliser


les lectures ou écritures de chaı̂nes et les traitements
classiques tels que concaténation, recopie, comparaison,
extraction de sous-chaı̂ne, conversions...

Prof. R. HANNANE (FSSM) Programmation II 7 / 38


Les chaı̂nes de caractères

Représentation des chaı̂nes


La convention adoptée

Problème:
Comme il n’existe pas de variables de type chaı̂ne
⇒ Il faudra prévoir un emplacement pour accueillir ces
informations

Solution:
I Un tableau de caractères

I Créer dynamiquement des emplacements mémoire,


lesquels seront alors repérés par des pointeurs

Prof. R. HANNANE (FSSM) Programmation II 8 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Chaı̂ne et tableaux
Une chaı̂ne de caractères n’est rien d’autre qu’un tableau de
type char
char chaine [7];

En C, la chaı̂ne de caractères est représentée par une suite


d’octets correspondant à chacun de ses caractères, le
tout étant terminé par un octet supplémentaire
contenant le caractère de fin de chaı̂ne: ’\0’
⇒ une chaı̂ne de n caractères occupe en mémoire un
emplacement de n+1 octets
Attention:
Il faut toujours ajouter un bloc de plus dans le tableau pour
stocker ce caractère ’\0’, c’est impératif !
Prof. R. HANNANE (FSSM) Programmation II 9 / 38
Les chaı̂nes de caractères

Chaı̂ne de caractère
Chaı̂ne et tableaux
Bonne déclaration et initialisation:
char chaine[8]={’e’,’x’,’e’,’m’,’p’,’l’,’e’,’\0’};
char chaine[10]={’e’,’x’,’e’,’m’,’p’,’l’,’e’,’\0’};
char chaine[]={’e’,’x’,’e’,’m’,’p’,’l’,’e’,’\0’};
char chaine[8]=”exemple”;
char chaine[10]=”exemple”;
char chaine[]=”exemple”;
Attention au mouvaise déclaration et initialisation:
char chaine[5]={’e’,’x’,’e’,’m’,’p’,’l’,’e’,’\0’};
char chaine[5]=”exemple”;
char chaine[8];
chaine=”exemple”;
Prof. R. HANNANE (FSSM) Programmation II 10 / 38
Les chaı̂nes de caractères

Chaı̂ne de caractère
Chaı̂ne et tableaux

Bonne affectation: Attention au mouvaise affectation


char chaine[] = ”exemple”; chaine[2] = ”a”;
chaine[2] = ’a’; chaine = ”ex”;
chaine[8] = ’s’;
Puisque chaı̂ne de caractères est un tableau d’objets de type
char, se terminant par le caractère nul ’\0’,
⇒ donc On peut manipuler toute chaı̂ne de caractères à
l’aide d’un pointeur sur un objet de type char
On peut faire subir à une chaı̂ne définie par char * chaine ;

des affectations comme chaine = " exemple " ;

Prof. R. HANNANE (FSSM) Programmation II 11 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Chaı̂ne et pointeurs

Ce programme imprime le nombre de caractères d’une chaı̂ne


(sans compter le caractère nul)
Exemple 2:
# include < stdio .h >
int main ()
{
int i ;
char * chaine ;
chaine = " chaine de caracteres " ;
for ( i = 0; * chaine != ’ \0 ’; i ++)
chaine ++;
printf ( " nombre de caracteres = % d \ n " ,i );
return 0;
} /* Affichage :
nombre de caracteres = 20
*/

Prof. R. HANNANE (FSSM) Programmation II 12 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Chaı̂ne et pointeurs

Pour la déclaration d’une chaı̂ne de caractères constante:

Bonne déclaration:
char *chaine = ”exemple”;

chaine = ”example”;

Attention:Mouvaise déclaration
char *chaine[] = ”exemple”;

char *chaine;
*chaine = ”example”;

Prof. R. HANNANE (FSSM) Programmation II 13 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes
Pour une chaı̂ne de caractères, on peut parcourir la
chaine et afficher caractère par caractère en utilisant le
spécificateur de format”%c”
En langage C, on peut simplement utiliser le spécificateur de
format ”%s” pour afficher toute la chaine exclus le
caractère ’\0’
char chaine [] = " exemple " ;
printf ( " % c " , chaine [3]); // m
printf ( " % s " , chaine ); // exemple

Exemple 3:
char prenom [20] ;
printf ( " Veuillez saisir votre prenom : " );
scanf ( " % s " , prenom );
printf ( " Bonjour % s " , prenom );

Prof. R. HANNANE (FSSM) Programmation II 14 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Problème:
Et si la chaine saisie par l’utilisateur contien le
caractère d’espacement, ex: Mohammed Reda, Fatima
Ezzahra, Jean Pierre,...???
⇒ Le scanf() ne stocke pas le caractère d’espacement dans
la variable de chaine de caractères
⇒ C’est juste la premiere partie qui va être stockée

Solution:
La fonction gets() permet de lire toute la ligne d’entrée
y compris des espaces
En plus, elle n’a pas besoin d’ajouter le spécificateur de
format ”%s”
Prof. R. HANNANE (FSSM) Programmation II 15 / 38
Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Note:
Avec le code ”%s” de scanf, on utilise les délimiteurs habituels
(l’espace ou la fin de ligne).
⇒ Le caractère délimiteur n’est pas consommé :
il reste disponible pour une prochaine lecture

Avec gets, seule la fin de ligne sert de délimiteur.


⇒ De plus, contrairement à ce qui se produit avec scanf, ce
caractère est effectivement consommé : il ne risque pas
d’être pris en compte lors d’une nouvelle lecture.

Prof. R. HANNANE (FSSM) Programmation II 16 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Pour afficher une partie d’une chaı̂ne, on doit spécifier le


nombre de caractères avec le spécificateur de format
”%s”

Exemple 4:
char prenom [20] ;
printf ( " Veuillez saisir votre prenom : " );
gets ( prenom ); // scanf ("%[^\ n ]%* c " , prenom );
printf ( " Bonjour % s \ n " , prenom );
printf ( " Les 3 premier caract è res de votre prenom
sont %.3 s \ n " , prenom );

Prof. R. HANNANE (FSSM) Programmation II 17 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Une autre façon pour afficher une chaı̂ne de caractères


sans utiliser le spécificateur de format ”%s” est l’emploie
de la fonction puts()

Cette fonction ajoute automatiquement un retour à la


ligne à la fin de la chaı̂ne

Exemple 5:
char prenom [20] ;
printf ( " Veuillez saisir votre prenom : " );
gets ( prenom );
puts ( prenom ); // printf ("% s \ n " , prenom );

Prof. R. HANNANE (FSSM) Programmation II 18 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Exemple 6:
# include < stdio .h >
int main ()
{
char nom [20] , prenom [20] , ville [25] ;
printf ( " Quelle est votre ville : " ) ;
gets ( ville ) ;
printf ( " Donnez votre nom et votre pr é nom : " ) ;
scanf ( " % s % s " , nom , prenom ) ;
printf ( " Bonjour % s % s qui habitez à " , prenom , nom ) ;
puts ( ville ) ;
return 0;
}
/*
Quelle est votre ville : Marrakech
Donnez votre nom et votre pr é nom : Rachidi Ilyass
Bonjour Rachidi Ilyass qui habitez à Marrakech
*/

Prof. R. HANNANE (FSSM) Programmation II 19 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Remarques:
Les fonctions printf et scanf permettent de lire ou d’afficher
simultanément plusieurs informations de type quelconque. En
revanche, gets et puts ne traitent qu’une chaı̂ne à la fois

Dans les appels des fonctions scanf et puts, les identificateurs de


tableau comme nom, prenom ou ville n’ont pas besoin d’être précédés
de l’opérateur & puisqu’ils représentent déjà des adresses. La norme
prévoit toutefois que si l’on applique l’opérateur & à un nom de tableau,
on obtient l’adresse du tableau. Autrement dit, &nom est équivalent à
nom.

La fonction puts réalise un changement de ligne à la fin de l’affichage de


la chaı̂ne, ce qui n’est pas le cas de printf avec le code de format %s

Prof. R. HANNANE (FSSM) Programmation II 20 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Affichage et lecture des Chaı̂nes

Remarques:
La fonction gets fournit en résultat soit un pointeur sur la chaı̂ne lue
(c’est donc en fait la valeur de son argument), soit le pointeur nul en
cas d’anomalie

Etant donné que gets consomme la fin de ligne servant de délimiteur,


alors que le code %s de scanf ne le fait pas, il n’est guère possible,
dans le programme précédent, d’inverser les utilisations de scanf et de
gets (en lisant la ville par scanf puis le nom et le prenom par gets) :
dans ce cas, la fin de ligne non consommée par scanf amènerait gets à
introduire une chaı̂ne vide comme nom.
⇒ D’une manière générale, d’ailleurs, il est préférable, autant que
possible, de faire appel à gets plutôt qu’au code %s pour lire
des chaı̂nes.

Prof. R. HANNANE (FSSM) Programmation II 21 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Pour fiabiliser la lecture au clavier : le couple gets sscanf

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 en travaillant en deux temps :
I Lecture d’une chaı̂ne de caractères par gets (c’est-à-dire d’une
suite de caractères quelconques validés par ”return”)
I Décodage de cette chaı̂ne suivant un format, à l’aide de la
fonction sscanf
⇒ En effet, une instruction telle que :
sscanf ( adresse , format , li st e _v ar i ab le s )

effectue sur l’emplacement dont on lui fournit l’adresse (premier


argument de type char *) le même travail que scanf effectue
sur son tampon.
Prof. R. HANNANE (FSSM) Programmation II 22 / 38
Les chaı̂nes de caractères

Chaı̂ne de caractère
Pour fiabiliser la lecture au clavier : le couple gets sscanf

C’est quoi la difference??

La différence est qu’ici nous sommes maı̂tre de ce tampon

⇒ en particulier, nous pouvons décider d’appeler à


nouveau sscanf sur une nouvelle zone de notre choix (ou
sur la même zone dont nous avons modifié le contenu par
gets), sans être tributaire de la position du pointeur,
comme cela était le cas avec scanf

Prof. R. HANNANE (FSSM) Programmation II 23 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Pour fiabiliser la lecture au clavier : le couple gets sscanf
Exemple 7:
# include < stdio .h >
# define LG 80
int main ()
{ int n , compte ;
char c ;
char ligne [ LG +1] ;
do {
printf ( " Donnez un entier et un caract è re : " ) ;
gets ( ligne ) ;
compte = sscanf ( ligne , " % d % c " , &n , & c ) ;
} while ( compte < 2 ) ;
printf ( " merci pour % d % c \ n " , n , c ) ;
return 0;}
/*
Donnez un entier et un caract è re : abcd
Donnez un entier et un caract è re : a 125
Donnez un entier et un caract è re : 12 bonjour
merci pour 12 b
*/

Prof. R. HANNANE (FSSM) Programmation II 24 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

Il existe de nombreuses fonctions toutes prêtes de manipulation


des chaı̂nes dans la bibliothèque string.h.
⇒ Il faut l’inclure pour pouvoir les utiliser
Parmi ces fonctions:
1 strlen
2 strcpy / strncpy
3 strcat / strncat
4 strcmp
5 strchr / strrchr
6 strstr
7 ...
Prof. R. HANNANE (FSSM) Programmation II 25 / 38
Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

1 La fonction strlen calcule la longueur d’une chaı̂ne de


caractères (sans compter le caractère ’\0’)

Exemple 8:
# include < stdio .h >
# include < string .h >
int main ()
{
char chaine [] = " Bonjour les SMI4 " ;
int taille =0;
taille = strlen ( chaine );
printf ( " La chaine \" % s \" fait % d caracteres de long " ,
chaine , taille );
return 0;
}
/* Affichage :
La chaine " Bonjour les SMI4 " fait 16 caracteres de long
*/

Prof. R. HANNANE (FSSM) Programmation II 26 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

2 La fonction strcpy permet de copier une chaı̂ne à


l’intérieur d’une autre y compris le caractère ’\0’

3 La fonction strncpy permet de copier n caractères


d’une chaı̂ne de caractères à l’intérieur d’une
autre

Prof. R. HANNANE (FSSM) Programmation II 27 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

Exemple 9:
# include < stdio .h >
# include < string .h >
int main (){
char chaine1 [] = " Bonjour les SMI4 " ;
char chaine2 [50];
char chaine3 [50];
strcpy ( chaine2 , chaine1 );
puts ( chaine2 );
strncpy ( chaine3 , chaine1 ,6);
puts ( chaine3 );
return 0;
}
/* Affichage :
Bonjour les SMI4
Bonjou
*/

Prof. R. HANNANE (FSSM) Programmation II 28 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

4 La fonction strcat permet d’ajouter une chaı̂ne à la


suite d’une autre.
⇒ On appelle cela la concaténation

5 La fonction strncat permet d’ajouter n caractères


d’une chaı̂ne de caractères à la suite d’une autre

Prof. R. HANNANE (FSSM) Programmation II 29 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

Exemple 10:
# include < stdio .h >
# include < string .h >
int main (){
char chaine1 [] = " Bonjour " ;
char chaine2 []= " les SMI4 " ;
char chaine3 []= " 2022/2023 " ;
strcat ( chaine1 , chaine2 );
puts ( chaine1 );
puts ( chaine2 );
strncat ( chaine1 , chaine3 ,5);
puts ( chaine1 );
return 0;}
/* Affichage :
Bonjour les SMI4
les SMI4
Bonjour les SMI4 2022
*/

Prof. R. HANNANE (FSSM) Programmation II 30 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

6 La fonction strcmp permet de comparer deux chaı̂nes entre


elles caractère par caractère
Cette fonction retourne soit une valeur :

0 : Si les deux chaı̂nes sont identiques

positive : Si la valeur ASCII du premier caractère de la


première chaine est supérieurs à celui de la deuxième chaine

négative : Si la valeur ASCII du premier caractère de la


première chaine est inférieur à celui de la deuxième chaine

Prof. R. HANNANE (FSSM) Programmation II 31 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

Exemple 11:
# include < stdio .h >
# include < string .h >
int main (){
char ch1 [] = " Ali " ;
char ch2 [] = " Ali " ;
char ch3 [] = " ali " ;
char ch4 [] = " Ahmed " ;
printf ( " % d \ n " , strcmp ( ch1 , ch2 )); // 0
printf ( " % d \ n " , strcmp ( ch1 , ch3 )); // -1 ou -32
printf ( " % d \ n " , strcmp ( ch1 , ch4 )); // 1 ou 4
return 0;
}

Prof. R. HANNANE (FSSM) Programmation II 32 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

7 La fonction strchr permet de rechercher la première


occurence du caractère dans une chaine. Elle
renvoie l’adresse sur la case de chaine contenant
le caractère s’il existe, si non il renvoie NULL

8 La fonction strrchr est similaire à la fonction strchr, la


seule différence est qu’elle recherche la chaine dans
l’order inverse

Prof. R. HANNANE (FSSM) Programmation II 33 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

Exemple 12:
# include < stdio .h >
# include < string .h >
int main (){
char ch1 [] = " Bonjour les SMI4 " ;
printf ( " % s \ n " , strchr ( ch1 , ’j ’ )); // jour les SMI4
char * ch2 = strchr ( ch1 , ’o ’ );
printf ( " % s \ n " , ch2 ); // onjour les SMI4
printf ( " % s \ n " , strrchr ( ch1 , ’o ’ )); // our les SMI4
return 0;
}

Prof. R. HANNANE (FSSM) Programmation II 34 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Les fonctions de manipulation de chaı̂ne

9 La fonction strstr permet de rechercher une chaine


ou lieu d’un seul caractère ⇒ elle est similaire à la
fonction strchr

Exemple 13:
# include < stdio .h >
# include < string .h >
int main (){
char ch1 [] = " Bonjour les SMI4 " ;
printf ( " % s \ n " , strstr ( ch1 , " jour " )); // jour les SMI4
char * ch2 = strstr ( ch1 , " on " );
printf ( " % s \ n " , ch2 ); // onjour les SMI4
return 0;
}

Prof. R. HANNANE (FSSM) Programmation II 35 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
Généralités sur les fonctions portant sur des chaı̂nes

En C, les fonctions de manipulation de chaı̂nes travaillent


toujours sur des adresses
Tout d’abord, rappelons qu’il n’y a pas de véritable type
chaı̂ne en C, mais simplement une convention de
représentation. On ne peut donc jamais transmettre la
valeur d’une chaı̂ne, mais seulement son adresse, ou plus
précisément un pointeur sur son premier caractère.
⇒ Ainsi, pour comparer deux chaı̂nes, on transmettra à la
fonction concernée (ici, strcmp) deux pointeurs de type char*
Mieux, pour recopier une chaı̂ne d’un emplacement à un
autre, on fournira à la fonction voulue (ici, strcpy) l’adresse
de la chaı̂ne à copier et l’adresse de l’emplacement où
devra se faire la copie
Prof. R. HANNANE (FSSM) Programmation II 36 / 38
Les chaı̂nes de caractères

Chaı̂ne de caractère
Généralités sur les fonctions portant sur des chaı̂nes

Les fonctions de concaténation, c’est-à-dire de mise bout


à bout de deux chaı̂nes créent une nouvelle chaı̂ne à
partir de deux autres. Elles devraient donc recevoir en
argument trois adresses !
⇒En fait, C a prévu de se limiter à deux adresses en
convenant arbitrairement que la chaı̂ne résultante serait
obtenue en ajoutant la seconde à la fin de la première,
laquelle se trouve donc détruite en tant que chaı̂ne (en
fait, seul son \0 de fin a disparu...).

Prof. R. HANNANE (FSSM) Programmation II 37 / 38


Les chaı̂nes de caractères

Chaı̂ne de caractère
En résumé
Le type char est utilisé pour stocker
un et un seul caractère. Il stocke en réalité un nombre mais
ce nombre est automatiquement traduit par l’ordinateur à
l’affichage grâce à la table ASCII
En C, il n’existe pas d’opérateur ou de mot-clefs réservés
pour le traitement d’une suite de caractères ”chaines de
caracteres”. ⇒ Pour cela, on utilise un tableau de char
ou un pointeur de char
Toute chaı̂ne de caractère se termine par un caractère
spécial appelé ’\0’ qui signifie ”fin de chaı̂ne”
Il existe de nombreuses fonctions toutes prêtes de
manipulation des chaı̂nes dans la bibliothèque string. Il
faut inclure string.h pour pouvoir les utiliser
Prof. R. HANNANE (FSSM) Programmation II 38 / 38

Vous aimerez peut-être aussi