Chaines de caractères en C Mardi 9/5 1
Les constantes de type caractère En C une constante de type caractère est un nombre entier écrit sous la forme d un caractère entre apostrophes, comme a. La valeur d une constante de type caractère est égale à la valeur du caractère d après le code ASCII. Exemples: A vaut 65 a vaut 97 'B vaut 66 0 vaut 48 (+32 sur le code(a)) 2
Les variables de type caractère Pour declarer une variable de type char, on procède de la façon suivante: char c1, /* c1 est une variable de type caractère */ c2 = a ; /* c2 est une variable de type caractère initialisée à a */ 3
Les entrées et sorties #include <stdio.h> main(){ char c ; printf("taper un caractere: "); c = getchar(); putchar(c); // comme printf } 4
Exemple 1: lecture avec getchar Le prog suivant saisit une séquence de char à partir du clavier tant le caractère saisit n'est pas '.' #include <stdio.h> /* affiche le caractère tapé à l'écran */ main(){ int c=''; while (c!= '.') { c = getchar(); putchar(c); } } #include <stdio.h> main(){ int c; while((c =getchar())!= '.' ){ putchar(c); } 5
Les chaînes de caractères En C il n y a pas de variable de type chaîne de caractères. Une chaîne de caractère est un tableau de caractères se terminant par le caractère '\0' (le caractère nul ayant la valeur 0) Ainsi la chaîne Bonjour groupe! serait représentée de la façon suivante: char ch[]="bonjour groupe!"; 0 1 2 3 4 5 6 7 8 9 B o n j o u r g r 10 11 12 13 14 15 o u p e! \0 Une constante chaîne "a" se termine aussi par \0 : 0 1 a \0 6
Déclaration de chaînes de caractères en C char <NomVariable> [<Longueur>]; Exemple : char NOM [9], TXT[] = "BONJOUR"; La représentation interne d'une chaîne de caractères est terminée par le symbole '\0' (NUL). Ainsi, pour un texte de n caractères, nous devons prévoir n+1 octets. 0 1 2 3 4 5 6 7 8 9 B O N J O U R \0 7
Saisie d'une chaine à partir du scanf avec le format %s: char chaine[10]; clavier printf("entrer une chaine de caractères: "); scanf("%s", &chaine); Délimiteur pour la lecture avec scanf: La fin de ligne ou le caractère espace On ne peut pas saisir des chaines contenant des blancs Le délimiteur n'est pas consommé par le scanf Il reste dans le tampon de lecture et sera consommé automatiquement par le prochain scanf 8
Saisie d'une chaine à partir du clavier 9
Affichage d'une chaine 10
char ch[]="bonjour groupe!"; puts(ch); puts("taper une chaine(max 16 car)"); gets(ch); puts("vs avez tape"); puts(ch);.. 11
#include <stdio.h> #define N 80 main(){ char str[n]; int i; printf("entrez une chaîne (max 80 car) :"); gets(str); puts(str); printf("\n"); // ou caractere par caractere for (i = 0; str[i]!='\0'; i++) printf("%c", str[i]); printf("\n"); } 12
Précédence lexicographique des chaînes de caractères a) La chaîne vide "" précède lexicographiquement toutes les autres chaînes. b) La chaîne A = "a1a2a... ap" (p caractères) précède lexicographiquement la chaîne B = "b1b2... bm" (m caractères) si l'une des deux conditions suivantes est remplie: 1) 'a1' < 'b1' 2) 'a1' = 'b1' et "a2a3... ap" précède lexicographiquement "b2b3... bm" Exemples "ABC" précède "BCD" "ABC" précède "B" "Abc" précède "abc" "ab" précède "abcd" car 'A'<'B' car 'A'<'B' car 'A'<'a' car "" précède "cd" " Ab" précède "ab" 'A' precede 'a' (ASCII(A)= 65 et ASCII(a)= 97) 13
En tenant compte de l'ordre alphabétique des caractères, on peut contrôler le type du caractère (chiffre, majuscule, minuscule). Exemples if (C>='0' && C<='9') printf("chiffre\n"); else{ if (C>='A' && C<='Z') printf("majuscule\n"); else { if (C>='a' && C<='z') printf("minuscule\n"); } } convertir des lettres majuscules en minuscules: if (C>='A' && C<='Z') C = C+ 32; ou vice-versa: if (C>='a' && C<='z') C = C- 32; 14
ctype.h Le fichier d en-tête ctype.h contient la déclaration de fonctions destinées à tester les caractères: isdigit(char c) retourne 1 si c est un chiffre, 0 sinon islower(char c) retourne 1 si c est une lettre minuscule, 0 sinon isupper(char c) retourne 1 si c est une lettre majuscule, 0 sinon isalpha(char c) retourne 1 si c est une lettre, o sinon isspace(char c) retourne 1 si c est un character d'espacement, 0 sinon 15
Fonctions de manipulation de chaines La librairie standard de C fournit plusieurs fonctions de traitement de chaînes de caractères ; elles nécessitent le fichier d'entête #include <string.h> Les prototypes sont: strcpy (char dest[], char src[]) ; strcat (char dest[], char src[]); strcmp (char ch1[], char ch2[]); strlen(char ch[]); 16
strcpy strcpy ( destination, source) ; Elle copie le contenu de source dans destination. Le contenu de source n'est pas changé. La fonction strcpy () ne fait pas de vérification des limites en nombre de caractères de la chaîne copiée. Le tableau de car qui la reçoit doit être suffisamment grand pour la contenir, sans oublier le caractère de fin '\0'. char str[80]; strcpy (str, "bonjour"); printf ("%s", str); 17
Exemple : Copier une chaîne sans utiliser la fct strcpy #include <stdio.h> #define N 50 /* copier: copie le tableau de dans le tableau vers ; on supose que le tableau vers est assez long */ char de[n], vers[n] ; int i = 0; while ( (vers[i] = de[i])!= \0 ) i = i + 1; } vers[i]= '\0';. 18
strcat strcat (destination, source) ; Elle ajoute le contenu d'une chaîne à la suite d'une autre. Ceci est appelé concaténation. strcat() ajoute le contenu de source au contenu de destination. char str[25]; strcpy(str, "bonjour "); strcat(str, "tout le monde!"); puts(str); b o n j o u r \0 b o n j o u r t o u t l e m o n d e! \0 Astuce Attention à la longueur de destination! 19
strcmp strcmp (s1,s2) ; Elle compare deux chaînes; elle renvoie: 0 : si les chaînes sont identiques, -1: si s1 < s2 s1 précède s2 +1: si s1 > s2 s1 succède s2 printf ("%d", strcmp ("un", "un")); /* affiche 0 */ printf ("%d", strcmp ("Un", "un")); /* affiche -1 */ printf ("%d", strcmp ("un", "Un")); /* affiche 1 */ 20
strlen strlen (str) ; Elle renvoie la longueur en nombre de caractères de la chaîne str. La fonction strlen() ne compte pas le caractère de terminaison '\0'. printf ("%d", strlen("essai")); /* affiche 5 */ 21
Exercice Ecrire un programme qui lit une chaine de caractères (max 20 caractères y compris '\0') on suppose que la chaine ne contient pas de chiffres ; la mémorise dans une variable CH1 puis convertit dans une nouvelle chaine CH2 les caractères minuscules de CH1 en majuscules et vice versa puis affiche les chaines CH1 et CH2 à l'écran. Exemple: CH1: TeSte CH2: teste 22
#include <stdio.h> #include<string.h> #define N 20 // on ajoute 1 pour \0 main(){ char CH1[N], CH2[N]; /* chaîne donnée et convertie*/ int i; /* Saisie de CH1 */ printf("entrez une chaine CH1 (max.19 caracteres) :\n"); gets(ch1); puts(ch1); for (i=0; i<strlen(ch1); i++) {//ou CH1[i]!='\0'ou CH1[i]!= '\n' if(ch1[i]>='a' && CH1[i]<='Z') // CH1[i] est majuscule CH2[i]=CH1[i]+32; // Maj en Min if(ch1[i]>='a' && CH1[i]<='z') // CH1[i] est majuscule CH2[i]=CH1[i]-32; // Min en Maj }// for CH2[i]='\0'; // fin de CH2 printf("\nch2:"); puts(ch2); } 23
Exercice Un mot est dit palindrome si on inverse l'ordre de ses lettres on obtient le même mot. Exemple:"radar", "ELLE". Ecrire un programme qui lit un mot (sans espaces blancs) et vérifie s'il est est palindrome ou non. Test d'exécution: Donner un mot: radar : est un palindrome Teste: n'est pas un palindrome 24
#include <stdio.h> #include <string.h> #define N 256 void main(){ char s[n]; int l = 0, r, palindrome=1; // on suppose que la chaine est palindrome puts("une chaine: "); scanf("%s", s); r = strlen(s)-1; while (l<r && palindrome){ printf("l=%d r=%d %c %c\n", l, r, s[l], s[r]); if (s[l]!= s[r]){ palindrome=0; } l++; r--; } if (palindrome==0 ) printf("%s n'est pas palindrome\n", s); else printf("%s est palindrome\n", s); } 25