Vous êtes sur la page 1sur 11

INTRODUCTION

Comme dans tout ouvrage, nous n’allons pas oublier de mettre une petite introduction de
cette synthèse qui va comporter les points basiques de cette exploration en programmation
procédurale, ceci est une synthèse qui explique quelques points bref sur les chaines des
caractères avec comme point basique :

 La présentation des chaines en C


 La déclaration des chaines en C
 L’accès et l’affectation des chaines en C
 L’affichage de chaines en C
 Les fonctions standard en C
 Les tableaux des chaines de caractères
BREVE RESUME SUR les Chaînes de caractères
Présentation des chaînes en C
En C la chaîne est présentée par un tableau unidimensionnel de caractères mais il y a une convention
qui permet la représentation et le traitement des strings – la fin de la chaîne actuelle est dénotée par '\
0' (le caractère avec code zéro) (Fig.1.1).

'B' 'o' 'n' 'j' 'o' 'u' 'r' '\0' ? ? Fig.1.1

En langage C, char est le type de donnée permettant de stocker des caractères. Nous avons vu, dans le
cours de programmation, que char fait partie des types de données numériques.
Le choix de ce type numérique pour stocker des caractères est lié à la façon dont le langage C stocke ses
caractères. La mémoire de l’ordinateur conserve toutes les données sous forme numérique. Il n’existe
pas de méthode pour stocker directement des caractères. Chaque caractère possède son équivalent en
code numérique : c’est le code ASCII (American Standard Code for Information Inter change). Ce code
attribue les valeurs 0 à 255 aux lettres majuscules et minuscules, aux chiffres, aux marques de
ponctuation et autres symboles.
Par exemple, 97 est l’équivalent ASCII de la lettre a. Quand vous stockez le caractère a dans une variable
de type char, vous stockez en réalité la valeur 97.
La question que l’on peut maintenant se poser est : comment le programme sait-il si une variable de type
char est un caractère ou un nombre ? L’utilisation le dira :
 Si une variable char est utilisée à un endroit du programme où un caractère est attendu, elle sera
interprétée comme un caractère.
 Si une variable char est utilisée à un endroit du programme où un nombre est attendu, elle sera
interprétée comme un nombre.
Les chaînes
Les variables de type char ne peuvent recevoir qu’un caractère, leur utilisation est donc limitée. Il
n’existe pas de type de donnée pour les chaînes de caractères. Un nom ou une adresse sont des
exemples de chaînes de caractères. Le langage C manipule ce genre d’informations à l’aide des
tableaux de caractères.
Tableaux de caractères
Pour stocker une chaîne de six caractères, il faut déclarer un tableau de type char avec sept éléments :
char chaine[7];
Une chaîne est une séquence de caractères qui se termine par le caractère nul \0. C’est le septième
élément. Bien qu’il soit représenté par deux caractères (antislash et zéro), le caractère nul est interprété
comme un seul caractère et sa valeur ASCII est 0.
Si un programme C stocke la chaîne Alabama, il stocke les sept caractères A, l, a, b, a, m et a, suivis du
caractère nul. Il faut donc un tableau de huit éléments. 64
La taille d’une variable de type char est d’un octet. Le nombre d’octets d’un tableau de caractères sera
donc égal au nombre d’éléments.
Déclaration de chaines

La convention permet de définir des chaînes constantes :

#define salutation "Bonjour"


On déclare une variable comme un tableau de char, dont la taille est égale à la longueur maximale de la
chaîne plus un. C'est pour qu’on puisse stocker le caractère '\0' dénotant la fin.
char chaine[10]; // la longueur maximale = 9

Comme toutes les autres variables, une variable char doit être déclarée, et elle peut être initialisée
dans la même instruction :
char a, b, c ; /* Déclaration de trois variables char non initialisées */
char code = ‘x’; /* Déclaration d’une variable char appelée code dans laquelle on stocke le caractère
x */
code = ‘!’; /* On stocke le caractère ! dans la variable code */
Pour créer des constants caractères, le caractère doit être entouré de guillemets simples. Le
compilateur le convertit automatiquement dans le code ASCII correspondant et la valeur du code
est attribuée à la variable.
Vous pouvez créer des constantes caractère symboliques en utilisant l’ordre
#define ou le mot clé const.
#define IX ‘x’
char code = IX; /* code égal ‘x’ */
const char A = ‘Z’

Initialisation
La chaîne peut être initialisée un tableau ordinaire (ex.1 et ex.2), mais dans ce cas on ne doit pas
oublier le caractère '\0'. Elle peut être initialisée par une constante littérale et dans ce cas le
compilateur va stocker le zéro s'il y a place. On peut initialiser un pointeur avec un littérale mais
dans ce cas le pointeur va designer la constante et on ne peut plus changer les caractères (fig. 8.2).
char machaine1[ ]= {'B','o','n','j','o','u','r','\0'}; // ex.1
char machaine2[10]= {'B','o','n','j','o','u','r','\0'}; // ex.2
char machaine3[ ]= "Bonjour"; // ex.3
char machaine4[8]= "Bonjour"; // ex.4
char *p = "Bonjour";// Attention c'est constante

Fig.1.2
char a[ ]= "Bonjour";
char *p= "Bonjour";

a : b o n j o u r \0
P : b o n j o u r \0

Vous pouvez aussi utiliser la chaîne littérale, séquence de caractères entre guillemets, qui est plus facile à
écrire et à lire :
char chaine[10] = "Alabama";

Dans ce cas, le compilateur ajoute automatiquement le caractère nul à la fin de la chaîne. De même, si la
taille du tableau n’a pas été indiquée, le compilateur la calculera. La ligne suivante, par exemple, crée et
initialise un tableau de huit éléments :
char chaine[ ] = "Alabama";
Le caractère nul permet aux fonctions qui manipulent des chaînes de caractères de connaître la longueur
de la chaîne. Si vous l’avez oublié, la fonction n’a aucun autre moyen de déterminer la fin de la chaîne ;
elle va continuer à traiter les données en mémoire tant qu’elle ne rencontre pas de caractère nul.
On doit faire attention d'avoir assez de place pour tous les caractères y compris le '\0' final. Dans le
premier exemple ci-dessous le compilateur va stocker la chaîne mais sans le zéro final et quand on utilise
cette variable au cours de déroulement du programme il y aura une erreur d'exécution car on ne peut pas
trouver la fin du string. Dans le deuxième exemple la place n'est pas suffisante et il y aura une erreur de
compilation. (Fig1.3)
char ch1[7]= "Bonjour";// erreur d'exécution Fig.1.3
char ch2[6]= "Bonjour"; //erreur de compilation

Accès et affectation (Chaînes et pointeurs)

 Accès aux caractères individuels


La chaîne est un tableau dont les éléments sont des caractères, donc l'accès aux caractères individuels est
comme aux éléments du tableau (fig. 1.4)
'B' 'o' 'n' 'j' 'u' 'r' ' '\0' ? ?

 Affectation et initialisation
Une chaîne de caractères est stockée dans un tableau de type char, et la fin de cette chaîne est
représentée par le caractère nul. Pour définir une chaîne, il suffit donc de pointer au début de cette
chaîne. L’utilisation du nom du tableau dans lequel elle est stockée, non suivi de crochets, est la méthode
standard d’accès à une chaîne de caractères. La bibliothèque standard de C contient de nombreuses
fonctions qui manipulent des chaînes de caractères. Pour passer une chaîne en argument, la fonction
s’attend à recevoir le nom du tableau dans lequel elle est stockée. C’est la méthode à utiliser avec les
fonctions de la bibliothèque, en particulier avec printf ( ) et puts( ) que nous allons voir.(fig1.5)
Char machaine[10]={'B','o','n','j','o','u','r','\0'};
char machaine[10]= "Bonjour"; Fig1.5

Quand un pointeur est déclaré et initialisé avec une chaîne constante (littéral), qui est le seul
moyen, sa valeur devient l'adresse du premier caractère de la chaîne. Dans ce cas les caractères ne
sont pas copiés.
char *p = "Bonjour";

On ne peut pas affecter directement une chaîne à une autre chaîne parce que le nom de la chaîne est le
nom d'un pointeur constant et l'affectation essaie de changer sa valeur (la valeur du premier caractère)
avec l'adresse du premier caractère de première chaîne. Les caractères ne sont pas copiés(fig1.6)
char machaine[10];
Fig1.6
machaine = "Bonjour";// erreur - machaine est un pointeur constant

L'affectation à un pointeur est valide est dans ce cas le pointeur va designer la nouvelle chaîne. Mais
seulement l'adresse est copiée, et non les caractères.
char p;
p = "Bonjour";//c'est bon

Pour copier les caractères c'est-à -dire pour créer une copie d'une chaîne on doit copier caractère par
caractère (fig. 1.7) dans une boucle. Ci-dessous sont montrés deux exemples d'une fonction pour la copie
des chaînes.
void chainecop(char *a, const char *de){ void chainecop(char *a, const char *de){Fig1.7
int i ; while (*de !='\0') *a++ = *de++;
for (i=0; de[i] !='\0';i++) a[i]=de[i]; *a ='\0';
a[i]='\0'; }
}

Affichage de chaînes et de caractères (Entrée-sortie des chaînes)

Un programme qui manipule des chaînes de caractères a souvent besoin de les afficher à l’écran. Les
deux fonctions utilisées sont puts ( ) et printf ( ).En dehors de ses deux fonctions il y’a d’autres fonctions
que nous allons ajouter dans la suite.
 La fonction puts ()
La fonction puts () reçoit en argument le pointeur vers la chaîne de caractères qu’elle va afficher à l’écran. Cette
fonction permet d’afficher les chaînes littérales aussi bien que les variables, et elle ajoute un retour à la ligne à la
suite de chaque chaîne qui lui est confiée.
Exemple d’utilisation de la fonction puts ()

/* Affichage de texte à l’écran avec puts ( ). */


#include <stdio.h> L’exécution de ce programme donne :
#include <stdlib.h> La polytechnique
#include<conio.h> est la
char *message1 = "La polytechnique"; meilleur
char *message2 = "est la"; faculté du
char *message3 = "meilleur"; monde.
char *message4 = "faculté de";
char *message5 = "du monde !";
int main( )
{
puts(message1) ;
puts(message2) ;
puts(message3) ;
puts(message4) ;
puts(message5) ;
do{ }
while(kbhit( )==0) ;  La fonction
} printf( )
Comme puts (), la fonction de bibliothèque
printf () permet d’afficher des textes à
l’écran. Elle utilise pour cela une chaîne format, qui contient des ordres de conversion et met en forme le
texte à afficher. Quand ce texte contient une chaîne de caractères, l’ordre de conversion à utiliser est %s.
Quand printf () rencontre l’ordre de conversion %s dans sa chaîne format, elle l’associe à l’élément
correspondant de sa liste d’arguments. Cet argument doit être un pointeur vers le début de la chaîne que
l’on veut afficher. Printf () va afficher tous les caractères à partir de cette adresse, jusqu’à ce qu’elle
rencontre la valeur 0. Par exemple :

char *str = "Un message à afficher";


printf ("%s", str);
Il est possible d’afficher une combinaison de plusieurs chaînes de caractères avec du texte littéral et/ou des
variables numériques
char *banque = "Banque Centrale du Congo";
char *nom = "SciencesPrint";
int solde = 100000;
printf("Le solde à la %s de la société %s est de %d euros", banque, nom, solde);
Le message affiché à l’écran sera : Le solde à la Banque de France de Jean Dupont est de 100000 euros.
 La fonction fgets ()

La fonction fgets () lit une chaîne de caractères entrée au clavier par l’utilisateur. Quand cette
fonction est appelée, elle lit tout ce qui est tapé sur le clavier, jusqu’à ce que l’utilisateur enfonce la
touche de retour à la ligne (touche Entrée). La fonction prend en compte le retour à la ligne, ajoute
un caractère nul en fin de chaîne et renvoie la chaîne (tronquée si nécessaire à la taille indiquée en
argument) au programme appelant. Cette chaîne est stockée à l’adresse indiquée par le pointeur de
type char qui a été passé à fgets (). Pour appeler fgets () dans votre programme, vous devez inclure
le fichier en-tête stdio.h.
Exemple d’utilisation de fgets () pour lire une chaîne de données entrée au clavier :

#include <stdio.h>
#include<conio.h>
char input[81]; /* Allocation d’un tableau de caractères pour recevoir les données. */
int main()
{
puts("Saisissez votre prénom, puis appuyez sur Entrée");
fgets(input,sizeof(input), stdin));
printf ("Vous avez tapé : ’%s’\n", input);
do{}
while(kbhit()==0) ;
}

Le résultat affiche :
Saisissez votre prénom, puis appuyez sur Entrée
Cela est un test
Vous avez tapé : Cela est un test
 La fonction scanf()
La fonction de bibliothèque scanf() permet de lire les données numériques entrées au clavier. Pour
cela, cette fonction utilise une chaîne format qui lui indique comment les lire. Si vous introduisez
l’ordre de conversion %s, scanf() pourra lire une chaîne de caractères. Comme pour la fonction
fgets(), on passe à scanf() un pointeur vers le bloc mémoire qui contiendra la chaîne.
Pour cette fonction, le début de la chaîne est le premier caractère non blanc qui est lu. Il y a deux
manières de lui indiquer la fin de la chaîne. Si %s est utilisé dans la chaîne format, la chaîne sera lue
jusqu’au premier caractère blanc rencontré (celui-ci ne fera pas partie de la chaîne). Si la chaîne
format contient %ns (ou n est une constante entière qui indique la longueur du champ), scanf() lira
les n caractères, mais s’arrêtera au premier blanc rencontré s’il arrive avant. Pour la même raison
que vous devez utiliser fgets () et non gets (), vous indiquerez impérativement %ns dans la chaîne
format et ne ferez jamais usage de %s avec scanf (). Sinon, cette fonction pourrait lire plus de
caractères que la chaîne ne peut en contenir, impliquant ensuite un comportement inattendu du
programme.
Vous pouvez lire plusieurs chaînes avec la même fonction scanf (), les règles précédentes
s’appliqueront pour chaque chaîne.
 Par example: scanf ("%10s%14s%11s", s1, s2, s3);
Si vous tapez janvier février mars en réponse à cette instruction, s1 sera égale à janvier, s2 à février
et s3 à mars. Si vous tapez septembre en réponse à l’instruction suivante :
Scanf ("%3s%3s%3s", s1, s2, s3); les valeurs de s1, s2 et s3 seront respectivement sep, tem et bre.
Si vous ne tapez pas le nombre de chaînes requis, la fonction attendra les caractères suivants, et le
programme ne continuera que lorsqu’elle les aura obtenus.
 Example: scanf ("%10s%14s%11s, s1, s2, s3);
Si la réponse à cette instruction est :
Janvier février
Le programme est suspendu et attend la troisième chaîne spécifiée dans la chaîne format. Si vous
tapez plus de chaînes que n’en contient la chaîne format, les chaînes supplémentaires vont rester
dans la mémoire tampon du clavier, en attendant la prochaine instruction scanf () ou une autre
fonction d’entrées/sorties. Imaginons, par exemple, que vous répondiez janvier février mars aux
instructions suivantes :
Scanf ("%10s%14s", s1, s2);
Scanf ("%11s", s3); la fonction attribuera janvier à la chaîne s1, février à la chaîne s2 et mars à s3.
La fonction scanf () renvoie une valeur entière égale au nombre d’éléments lus avec succès. On
ignore cette valeur la plupart du temps. Si le programme ne lit que du texte, il faut choisir fgets ()
plutô t que scanf ().
Cette dernière est particulièrement indiquée quand vous avez à lire une combinaison de textes et de
valeurs numériques. N’oubliez pas qu’il faut utiliser l’opérateur d’adresse (&) pour lire des variables
numériques avec scanf ().
Cette exemple renferme toutes les fonctions dont on a eu à parler

#incude <stdio.h>
void main (void) {
char ch1[50] ;
char ch2[10] ;
int i;
scanf ("%s", ch1); puts(ch1);
printf("%s\n",ch1);
gets(ch1); puts(ch1);
printf("%s\n",ch1);
fgets(ch1,50,stdin); puts(ch1);
scanf("%5s%d",ch2,&i);
printf("|%s| |%d|\n",ch2,i);
printf("|%5.2s| |%3d|\n",ch2,i);

Le

C'est une chaine de caracteres


C'est Le résultat
C'est
une chaine de caracteres
une chaine de caracteres
Une autre chaine de caracteres
Une autre chaine de caracteres
abcd123
|abcd1| |23|
| ab| | 23|

Les fonctions standard


Les fonctions standard qui manipulent les chaînes de caractères sont nombreuses. Ici nous allons donner
quelques d'eux. Elles sont montrées avec les nom des fichiers en-tête (header files) dans lesquels se trouvent
leurs définitions.

 La longueur
int strlen(char *s) – string.h Rends la longueur de s, c'est à dire le nombre de caractères qui se trouvent entre
l'adresse qui est la valeur de s et le premier caractère '\0'.

 Fonctions de conversion
int atoi(char *s ) – stdlib.h Elle convertit s (qui doit être la présentation d'un nombre entier) dans un entier
long atol(char*) – stdlib.h Elle convertit s (qui doit être la présentation d'un nombre entier) dans un entier
long.
double atof(char*) – stdlib.h Elle convertit s (qui doit être la présentation d'un nombre réel) dans un double.
char *itoa(int value, char *string, int radix) – stdlib.h Elle représente la valeur entière value dans une chaîne
string dans le système numérique de base radix.
int toupper(int ch) – ctype.h Elle rends le caractère ch converti en majuscule.
int tolower(int ch) – ctype.h Elle rends le caractère ch converti en minuscule.

 Concaténation et copie
Ces fonctions ont deux variants:
• fonction simple – qui traite toute la chaîne n'import quelle est sa longueur.
• fonction avec restriction – elle traite au maximum maxl caractères, où maxl est un paramètre entier. Ces
fonctions ont un n supplémentaire dans leurs noms.

char *strcat(char *dest, const char *src) – string.h Elle colle une copie de src au dest
char *strncat(char *dest, const char *src, size_t maxlen) Elle colle une copie de src au dest mais au maximum
maxl caractères et elle n'ajout pas un '\0'.
char *stpcpy(char *dest, const char *src) – string.h Elle copie src au dest.
char *strncpy(char *dest, const char *src, size_t maxlen) Elle copie src au dest mais au maximum maxl
caractères et elle n'ajout pas un '\0'.

 Comparaison
int strcmp(const char *s1, const char *s2) – string.h Comparer les s1 et s2. Le résultat est : -1 – s1>s2, 0 –
s1=s2, 1 – s1<s2
int strncmp(const char *s1, const char *s2, size_t maxlen) Comparer les s1 et s2. Le résultat est : -1 – s1>s2, 0
– s1=s2, 1 – s1<s2. Mais elle traite au maximum maxl caractères.
int stricmp(...), int strincmp(...) – Elles comparent les chaînes ignorant la différence entre majuscules et
minuscules

 Recherche
char *strchr(const char *s, int c) – string.h Elle cherche la 1-ère occurrence de c en s. Le résultat est pointeur
vers l'occurrence ou NULL si c n'existe pas
char *strrchr(const char *s, int c) Elle cherche la dernière occurrence de c en s. Le résultat est pointeur vers
l'occurrence ou NULL si c n'existe pas

Fonctions de classification – ctype.h


int isalpha(int c) Elle rends 1 si c est une lettre et 0 dans l'autre cas.
int isdigit(int c) Elle rend 1 si c est un chiffre et 0 dans l'autre cas.
int isspace(int c)
Elle rend 1 si c est une espace, une tabulation ou nouvelle ligne et 0 dans les autres cas.
int isupper(int c) Elle rend 1 si c est une lettre majuscule et 0 dans l'autre cas.
int islower(int c) Elle rend 1 si c est une lettre minuscule et 0 dans l'autre cas.

Insertion et suppression

Rendre le résultat dans une autre chaîne


La fonction strdela supprime de la chaîne src les n caractères en commençant de celui à place numéro from et
stocke le résultat dans la chaîne dest.

char * strdela(char *dest, char *src, int from, int n){


if (from > strlen(src)) return src;
strncpy(dest,src,from; // copier les caractères avant les supprimés
dest[from]='\0'; //marque la fin de la première sous chaîne
strcat(dest, src+from+n); //coller les caractères après les supprimés
return dest;
}

La fonction insera insère la chaîne ins dans la chaîne src en commençant de caractère numéro from
et stocke le résultat dans la chaîne dest.

char* insera (char *dest, char *src, int from, char *ins) {
char *p=src+from; int i;
if (from > strlen(src)) return dest;
for(i=0;i<from;i++)dest[i]=src[i]; // copier les caractères avant l'insertion
// ou strncpy (dest, src, from)
dest[from]='\0'; //marque la fin de la première sous chaîne
strcat(dest,ins);// coller la chaîne insérée
strcat(dest,p); //coller les caractères après l'insertion
return dest;
}

Dans les deux fonctions il y a un paramètre dest pour le résultat. On ne peut pas créer une chaîne
dans la fonction et rendre l'adresse de cette chaîne par l'instruction return parce que la chaîne est
locale dans la fonction et va être détruit à la sorte de la fonction. De cette façon la valeur (l'adresse)
retournée

Rendre le résultat dans la même chaîne


La fonction strdel supprime de la chaîne s les n caractères en commençant de celui à place numéro
from et stocke le résultat dans la chaîne s.
char * strdel(char *s, int from, int n){
if (from > strlen(s)) return s;
if (from + n > strlen(s)) // copier les caractères avant les supprimés
n = strlen(s) - from; //calcule l'adresse du premier caractère après
//les supprimés
strcpy(s+from, s+from +n); //déplace les caractères après les supprimés
return s;
}

La fonction inser insère la chaîne ins dans la chaîne dest en commençant de caractère numéro from
et stocke le résultat dans la chaîne dest. La chaîne dest doit être assez large pour être capable de
contenir la chaîne résultat.
char* inser(char *dest, int from, char *src){
char *p=dest+from;
char *p1 = p+strlen(src);
int i;
if (from > strlen(dest)) return dest;
for(i=strlen(p);i>=0;i--)p1[i]=p[i]; //déplace les caractères après la place
//d'insertion à l'arrière pour libérer place pour l'insertion
strncpy(p,src,strlen(src)); //copier les caractères insérés à la place libre
return dest;

Tableaux de chaînes de caractères

Présentation de tableaux de chaînes


Chaque chaîne est un tableau unidimensionnel de caractères. Donc le tableau de chaîne sera un tableau
bidimensionnel. On peut distinguer quelques cas.
 Tableau rectangulaire
La présentation de la déclaration suivante est montrée à la fig. 8.8 les chaînes sont placées une après l'autre dans la mémoire.

char tc[3][7]= {"un","deux","trois"};

Dans ce cas on peut modifier les caractères des chaînes mais pas leur ordre.

tc [0][1] = 't';
strcat (tc[0],tc[1]);

Ce cours s'est largement appuyé sur les tableaux et les pointeurs pour introduire la notion de
Chaine de caracteres. Il ne s'agit en effet aucunement d'un type de base du langage mais d'une
construction à partir d'une séquence de char.
Ces derniers sont de petits entiers dont la correspondance avec des caracteres repose sur la
table ASCII. Le langage offre une facilite pour les saisir de manière littérale et la bibliothèque
Standard propose des fonctions traitant ces caracteres par catégories (lettres, chiffres…).
Les chaines de caracteres sont terminées par un caractère nul. Le langage offre une facilite
Pour les saisir de manière littérale et la bibliothèque standard propose des fonctions permettant de les
manipuler (recopie, comparaison…).

Vous aimerez peut-être aussi