Les chaînes de caractères

Slides:



Advertisements
Présentations similaires
Premier programme en C :
Advertisements

La boucle for : init7.c et init71.c
Introduction au Langage C,C++
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
GEF 243B Programmation Informatique Appliquée
GEF 243B Programmation informatique appliquée
C.
Tableaux Certains problèmes nécessitent beaucoup de variables du même type. Exemple : relevé de températures matin et soir dans 10 villes pour 10 jours.
Fonctions Dans un programme : certaines opérations (ou séquences d'opérations) peuvent se répéter plusieurs fois : affichage de tableau, saisie, ou même.
FLSI602 Génie Informatique et Réseaux
FLSI602 Génie Informatique et Réseaux
Principes de programmation (suite)
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Récursivité.
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
RESUMES Module II1 SOMMAIRE CYCLE 1 : Saisir – Afficher – Données
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
TRAITEMENT DE STRUCTURES
IFT-2000: Structures de Données Listes chaînées Dominic Genest, 2009.
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
Quest-ce quune classe dallocation? Une classe dallocation détermine la portée et la durée de vie dun objet ou dune fonction.
Les pointeurs Enormément utilisé en C/C++ ! Pourquoi? A quoi ça sert?
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
IFT-2000: Structures de données
Structures de données IFT Abder Alikacem La classe string Département dinformatique et de génie logiciel Édition Septembre 2009 Département dinformatique.
Sixième cours Les chaînes de caractères et le passage de paramètres par référence Passage de paramètres par référence String.h.
8PRO100 Éléments de programmation Les types composés.
LANGAGE C LP A2I IUT St DIE
Procédures et fonctions
Plan cours La notion de pointeur et d’adresse mémoire.
L’essentiel du langage C
Structures des données
Le langage C Structures de données
2.1 - Historique Chapitre 2 : Introduction au langage C++
Le langage C Rappel Pointeurs & Allocation de mémoire.
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
La notion de type revisitée en POO
Les adresses des fonctions
Les types.
8PRO107 Éléments de programmation Les chaînes de caractères.
Un survol du language C.
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Tutorat en bio-informatique
Strings et Tableaux en Java
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
Les types composés Les enregistrements.
Interprétation/Génération de code pour le langage Z minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
8PRO100 Éléments de programmation Les pointeurs de caractères.
Chaînes de caractères en langage c, c'est en fait un tableau
Fiabilisation des lectures au clavier. Problèmes liés à scanf: rencontre de caractères invalides Sans arrêt prématuré: compte = scanf(``%d%c``;&n,&c);
Conception de Programmes - IUT de Paris - 1ère année – Cours 8 – Les entrées/sorties Comment fonctionnent les opérateurs > pour les types élémentaires.
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Les variables fichiers. Le type fichier On manipule les fichiers par l’intermédiaire de structures FILE décrites dans stdio.h FILE *monFichier; –Nom physique.
Introduction au langage C Les entrées-sorties
Mettre en formeExaminerManipuler Les fonctions printf() et sprintf Le traitement de chaîne de caractère La fonction printf() formate le contenu d'une chaîne.
Conception de Programmes - IUT de Paris - 1ère année Quelques éléments du langage C++ Les références La surcharge de fonctions Les fonctions «
8PRO107 Éléments de programmation Les adresses et les pointeurs.
8PRO107 Éléments de programmation Les tableaux. Étude de cas 1 Description du problème : Lire une liste d’entiers et l’afficher d’abord dans le même ordre.
Exercices.
Les chaînes de caractères
1 Listes des méthodes de la classe string, et exemples.
Philippe Gandy - 22 septembre 2015 Basé sur les notes de cours de Daniel Morin et Roch Leclerc.
Exercices sur les pointeurs. lireCar/remettreCar Lorsque l’on lit caractère par caractère, on ne peut pas savoir qu’on a atteint un caractère avant de.
Philippe Gandy – 10 novembre 2015 Basé sur les notes de cours de Daniel Morin et Roch Leclerc.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
Informatique 1A Langage C 6 ème séance 1. Objectifs de la séance 6  Allocation dynamique de mémoire  Application à la création de tableaux 2.
M. BENJELLOUN : 2005 Le but final est de programmer un jeu où l'ordinateur choisira un nombre aléatoire entre 0 et 100 que vous devez deviner.
Transcription de la présentation:

Les chaînes de caractères

Important Il n’existe PAS de type ``chaîne de caractère`` en C Une abstraction de chaîne de caractère est donnée par un tableau de caractères Une chaîne de caractères valide est obligatoirement terminé par le caractère NULL ( i.e. \0)

Les constantes chaîne Suite de caractères placé entre `` Caractères utilisables: N’importe quel caractère du jeu de caractère source Les caractères de contrôle (\n, \t, \v, …) Sauf `` (que l’on peut obtenir par \``) ``ceci est \``correct\`` `` Sauf fin de ligne (qui doit apparaître sous \n) ``ceci n’est pas correct ``

Convention de représentation des constantes chaîne Le compilateur représente une chaîne sous une forme de tableau de manière conventionnée: ``bonjour`` amènera le compilateur à placer en mémoire la suite des caractères `b`,`o`,`n`,`j`,`o`,`u`,`r`,`\0` selon le norme, la notation sera convertie en un pointeur sur le premier caractère. Il s’agit donc d’un caractère de type char*. Tout se passe comme si la constante chaîne était un tableau de caractères.

Exemple #include stdio.h int main(void){ char *adr; Va s’arrêter lorsque \0 va être atteint Ne va afficher que ``bonjour`` #include stdio.h int main(void){ char *adr; adr = ``bonjour \0 Monsieur``; while(*adr){ printf(``%c``,*adr); adr++; }

Emplacement mémoire Une constante chaîne peut apparaître dans le programme source au niveau Global: Elle figure dans une initialisation ou une instruction de déclaration: char *mess=``bonjour``; ou char t[]= ``hello``; Remarque: t est une constante pointeur, t = ``salut ``; est interdit Local: Dans une déclaration ou dans une instruction: strcpy(adr,``salut``); Une constante chaîne est toujours placée en mémoire statique (alloué une fois pour toute avant l’exécution )

Risque de modification des constantes chaîne char *adr=``bonjour``; *adr = `x`; /* bonjour devient il xonjour?*/ *(adr+3) = `w`; /*bonjour devient il bonwour?*/ Soit la chaîne a été placée dans une zone protégée et une erreur d’exécution est levée. Soit la modification à lieu, que le caractère visé soit à l’intérieur ou à l’extérieur de la chaîne visée!

Comment se protéger? Déclarer les pointeurs constant. const char *adr = ``bonjour``; Interdit la modification de la chaîne pointée (adr est un pointeur sur un objet constant.) *adr = `x`; /*provoque une erreur de compilation*/ adr[i] = `x`; /*aussi*/ Mais toujours problème avec: scanf(``%s``,adr); et recopiage du pointeur dans un pointeur non constant (warning compilation) Remarque: pas de problème avec char t[20] = ``bonjour``; /* *(t+3)=`x`; est licite */

Créer, utiliser ou modifier une chaîne Le C manque d’unité quand à la manipulation des chaînes, on peut: Utiliser les fonctions de la bibliothèque standard qui travaillent sur la chaîne en se basant sur son zéro de fin. Manipuler individuellement chaque caractère (comme un parcours de tableau) dans ce cas; la détection de fin de chaîne est de votre responsabilité.

Comment disposer d’un emplacement pour y ranger une chaîne? Soit utiliser un tableau de caractères existant (déclaré), ce qui impose une taille maximale pour la chaîne de caractère qu’on pourra y ranger. Soit allouer dynamiquement, au moment de l’exécution un emplacement de la taille exacte de la chaîne à enregistrer. Dans les deux cas, le formalisme de manipulation de la chaîne est le même.

Comment agir sur le contenu d’une chaîne? L’initialiser lors de la réservation de son espace char ch[20] = ``bonjour``; (les 12 autres sont inconnus) Créer ou modifier individuellement chacun de ses caractères (ne pas oublier le caractère NULL en fin de chaîne) int main(void){ char chiffre[11]; int i; for(i=0;i10;i++) chiffre[i] = `0`+ i; chiffre[10] = `\0`; }

Comment agir sur le contenu d’une chaîne? (2) La modifier globalement avec les fonctions standard. Affectation n’est pas possible (pas de type string) mais fonction standard s’en charge: char ch1[10]=``bonjour``; char ch2[10]; strcpy(ch2,ch1); strcpy(ch2,``hello``); Modifier partiellement: jouer sur pointeru de début de chaîne. char ch1[20]=``bonjour``; char *ch2=``monsieur``; strcpy(ch1+2, ch2+4); /* donne bosieur dans ch1 */ Risques : dépasser les limites de la chaîne!

Comment utiliser une chaîne existante Caractère par caractère: quelle que soit la méthode utilisée pour créer la chaîne (allocation dynamique ou statique) le formalisme est le même: int main(void){ char mot[11]; int i; printf(``donner un mot de moins de 10 caractères:``); gets(mot); for(i=0;istrlen(mot);i++) printf(``%c \n``, mot[i]); }

Comment utiliser une chaîne existante Utilisation d’une partie d’une chaîne: caractère par caractère (cf avant) ou utiliser le formalisme du tableau: int main(void){ char ch[]=``bonjour monsieur``; puts(ch); puts(&ch[8]); /*ou puts(ch+8) */ } Donne: bonjour monsieur monsieur

Entrée-sorties standard de chaînes Etude sur les entrées-sorties standard généralisable pour tout type de fichier.

Les sorties int puts(const char *chaîne); (stdio.h) Renvoie à la sortie standard les différents caractères de la chaîne d’adresse chaîne, zéro de fin non compris puis transmet un caractère \n. Sa valeur de retour est non négative si tout se passe bien, EOF si une erreur. int printf(``%s``,*char); Ici, on ajoute pas de \n. Permet d’ajouter d’autre infos et de modifier la chaîne à l’affichage (nombre de caractères à utiliser…)

Lecture de chaînes char *gets(char *chaine); (stio.h) Lire les caractères de l’entrée standard en les rangeant dans l’adresse chaîne S’arrêter dès que \n ou EOF est rencontré. Le caractère \n n’est pas introduit en mémoire mais est consommé (retiré du buffer) Un caractère \0 est ajouté (à prévoir lors de l’allocation de mémoire). Retourne l’adresse de la chaîne si aucune erreur, NULL sinon

Lecture de chaîne (2) Avec scanf et %s On ne peut pas lire de chaîne commençant par un espace blanc (tabulation, espaces, …). Les espaces blancs sont utilisés comme délimiteurs. Il n’est donc pas possible de lire une chaîne contenant une espace! Le délimiteur est lu mais pas consommé: il reste disponible pour la prochaine lecture. scanf(``%s``,ch1); gets(ch2); avec bonjour  donnera ``bonjour`` dans ch1 et une chaîne vide dans ch2!

Manipulation de chaînes Fonctions standard de manipulation (string.h): Copie de chaîne Concaténation de chaîne Comparaison de chaîne Recherche de caractères Conversion en nombres Travaillent toujours par adresse (attention aux tailles des espaces)

La fonction strlen size_t strlen(const char *chaine) Fournit la longueur d’une chaîne dont on lui a transmis l’adresse en argument. Cette longueur correspond au nombre de caractères lus depuis l’adresse fournie jusqu’au caractères de code nul. (qui n’est pas compté).

Copie de chaîne Pas d’affectation possible Seule possibilité: recopier à une adresse donnée les caractères d’une chaîne située à une autre adresse. char *strcpy(char *but, const char *source) N’effectue aucun contrôle de longueur et ne s’assure pas de la présence d’un zéro à la fin char *strncpy(char *but, const char *source, size_t longueur) Si aucun \0 n’a été trouvé dans source au bout longueur caractères, il n’est pas ajouté: but ne sera pas une chaîne!

Exemple int main(void){ char ch1[20] = ``xxxxxxxxxxxxxxxxxxx``; printf(``donnez un mot: ``); gets(ch2); strncpy(ch1,ch2,6); printf(``%s``,ch1); } Donne: donnez un mot: bon bon\0xxxxxxxxxxxx\0

Concaténation de chaînes int main(void){ char cha1[50]=``bonjour``; const char *ch2 = `` monsieur``; printf(``avant: %s \n``,ch1); strcat(ch1,ch2); printf(``après: %s \n``,ch1); } Donne: avant: bonjour après: bonjour monsieur

Concaténation de chaînes char *strcat(char *but, const char *source); N’effectue aucun contrôle de longueur Ne s’assure pas de la présence d’un zéro en fin de chaîne. Attention aux chaînes qui se chevauchent char *strncat(char *but, const char *source, size_t longueur);

Comparaison de chaînes On ne dispose pas d’opérateur relationnels sur les chaînes de caractères (reviendrait à comparer des pointeurs…) int strcmp(const char *ch1, const char *ch2) int strncmp(const char *ch1, const char *ch2, size_t longueur) Effectuent une comparaison lexicographique La valeur de retour est positive si ch1 arrive avant ch2, nulle si elles sont égales et négative sinon

Recherche dans une chaîne Permet de chercher dans une chaîne la première occurrence : D’un caractère donné (strchr et strrchr) D’une autre chaîne (strstr) D’un caractère appartenant à un ensemble de caractère (strpbrk) Toutes ces fonctions fournissent l’adresse de l’information recherchée si elle existe, NULL sinon De plus: Extraire ou supprimer d’une chaîne un préfixe formé de certains caractères D’éclater une chaîne en plusieurs parties, en utilisant comme séparateurs des caractères de son choix (strspn, strcspn, strtok)

Recherche de carctères char *strchr(const char *chaine, int c); Permet de rechercher la première occurrence du caractère c (un int, pour ne pas se préoccuper de l’implémentation) strchr(``bonjour``,`o`); /* donne l’adresse du premier `o` */ char *strrchr(const char *chaine, int c); Même traitement à partir de la fin. strrchr(``bonjour``,`o`); /* donne l’adresse du dernier `o` */

Recherche de sous chaîne Permet de rechercher la première occurrence d’une chaîne donnée. char *strstr(const char *ch1, const char *ch2); Renvoie l’adresse de la premières occurrence ou NULL.

Recherche d’un caractère parmi plusieurs : strpbrk char *strpbrk(const char *ch1, const char *ch2); Retourne l’adresse de la première occurrence d’un des caractères de la chaîne ch2 dans la chaîne ch1 ou NULL. Exemple: remplacer les signes de ponctuations par un espace char ponct[] =``.,;:!?``; char ch[81]; char *ad; … ad =ch; while(ad = strpbrk(ad, ponct)) *ad=` `;

Recherche d’un préfixe size_t strspn(const *char ch1, const char *ch2); Fournit la longueur du ``segment initial`` d’une chaîne formée entièrement de caractères appartenant à un ensemble donné. strspn(``2587abc25``,``0123456789``); vaut 4 strspn(``XYZZYX``,``XYZ``); vaut 6 size_t strcspn(const *char ch1, const char *ch2); Fournit la longueur initiale d’une chaîne formée entièrement de caractères n’appartenant pas à un ensemble donné. strcspn(``abc25zxt``,``0123456789``); vaut 3

Fonction d’éclatement Eclater une chaîne en plusieurs sous-chaînes si on connaît les caractères de séparation. ``12h 45mn 42s`` en ``12``, ``45`` et ``42`` char *strtok(char *ch, const char *delimit) Renvoie l’adresse de la première sous-chaîne. char *adr, *ch, *delim; … adr = strtok(ch, delim); while(*adr){ adr = strtok(adr,delim); }

Fonctions de conversion d’une chaîne en nombre Fonctions universelles: strtol, strtoul, strtod Fonctions issue des premières implémentation: atoi, atof, atol conservées pour compatibilité Pas de fonction inverse (sprintf) Conversion en bloc de plusieurs strings par sscanf

Conversion en double: strtod double strtod(const char *ch1, char **carinv); strtod(``12.25``,NULL); /*donne environ 12.25 (double) */ strtod(``-2.2bob``,NULL); /*donne environ -2.2 (double) */ strtod(`` -1.5``,NULL); /*donne environ -1.5 (double) */ char *ad_car; strtod(`` 12e25bonjour``,&ad_car); /*donne environ 12e25 (double) et on obtient dans ad_car l’adresse de `b`*/

strtol et strtoul long strtol(const char *ch, char **carinv, int base) unsigned long strtoul(const char *ch, char **carinv, int base) Base précise la base dans laquelle le nomre est supposé être écrit. Si nul: en décimal

atof, atoi et atod double atof(const char *ch1); long atol(const char *ch2); int atoi(const char *ch3);

Fonctions de manipulation de suites d’octets. Permet de recopier des objets dont on connaît l’adresse et la taille sans pour autant connaître le type. (string.h) Fonctions de recopie memcpy, memmove Fonction de comparaison memcmp Fonction d’initialisation memset Fonction de recherche dans une suite d’octets memchr

Exercice Ecrire une fonction lireLigne qui lit au plus lim caractères de l’entrée standard et les retourne dans une chaîne jusqu’à la lecture de \n faire en sorte que la chaîne de sortie soit une chaîne! Renvoyer la longueur de la chaîne int lireLigne(char s[], int lim)

Correction int lireLigne(char s[], int lim){ int c, i; for(i=0; ilim-1 && (c=getchar()) != EOF) && c !=`\n`; i++) s[i] =c; if(c == `\n`){ s[i] = c; ++i;} s[i] = `\0`; return i; }

Exercice Ecrire une fonction qui inverse une chaîne de caractère void inverser(char s[]);

void inverser(char s[]){ int i,j; char temp; j=i=0; while(s[i] == `\0`) ++i; --i; if(s[i] == `\n`) --i; while(ji){ temp=s[j]; s[j] = s[i]; s[i] = temp; ++j; }

Exercice Ecrivez la fonction strlen int strlen(char *s);

Correction int strlen(char *s){ int n; for(n=0; *s != `\0`; s++) n++; return n; }