Cours de C

Chaines de caractères


Définition

● Une chaîne de caractères est un tableau de char contenant un caractère nul. Le caractère nul a 0 pour code ASCII et s'écrit '\0'.

● Les valeurs significatives de la chaîne de caractères sont toutes celles placées avant le caractère nul.

● On remarque donc que si le caractère nul est en première position, on a une chaine de caractères vide.

Déclaration

● Comme une chaîne de caractères est un tableau de char, on le déclare:

char <nom_chaine>[<taille_chaine>];

● Par exemple, on déclare une chaine c de 200 caractères de la sorte: char c[200];

● Le nombre maximal de lettres qu'il sera possible de placer dans c ne sera certainement pas 200 mais 199, car il faut placer après le dernier caractère de la chaîne un caractère nul.

Initialisation

● On initialise une chaîne a la déclaration, et seulement a la déclaration de la sorte:

char <nom_chaine>[<taille_chaine>] = <valeur_initialisation>;

● Ou la valeur d'initialisation contient la juxtaposition de caractères formant la chaîne entourée de guillemets ("").

● Exemple:
char c[] = "bonjour" ← →
char c[] = {'b','o','n','j','o','u','r','\0'}(taille alculée par le compilateur)

Accès aux éléments

● Du fait qu'une chaine de caractère est un tableau, il est aisé d'en isoler un élément. On teste donc si le premier caractère de c est une majuscule de la sorte:

if(c[0] >= 'A' && c[0] <= 'Z')
printf("Cette phrase commence par une majuscule \n");
else
printf ("Cette phrase ne commence pas par une majuscule \n");

● Cette propriété permet aussi d'afficher une chaîne de caractère par caractère:

int i = 0;
while (c[i] != 0)
printf ("%c" , c [i++]);

#include <stdio.h>

void main()
{
char D[27];
int i;

for(i = 0; i<26; i++)
D[i] = 'a' + i;
D[26] = 0;

printf("*******Affichage avec while*******\n");
i = 0;
while(D[i] != 0)
printf("\n%c", D[i++]);

printf("*******Affichage avec putchar*******\n");
i = 0;
while(D[i] != 0)
putchar(D[i++]);

printf("*******Affichage avec %%s*******\n");
printf("Vous avez saisi: \n %s \n", D);
}

Affichage avec "puts"

● puts écrit la chaîne de caractères désignée par <Chaîne> sur stdout et provoque un retour à la ligne.

● En pratique, puts(TXT); est équivalent à printf("%s\n", TXT);

Saisie avec "gets"

● Tout débordement d'indice et/ou absence de caractère nul peut donner lieu a des bugs difficiles a trouver


#include <stdio.h>

#define N 20

void main()
{
char chaine[N];
int i;

printf("Saisissez une phrase : \ n");
gets(chaine);
for(i = 0; chaine[i] != 0; i++)
printf("chaine[%d] = %c (code ASCII : %d )\n", i ,chaine[i], chaine[i]);
}

"fgets" au lieu de "gets"

fgets(<chaine>, <taille>, stdin);

● La taille de la chaîne saisie est limitée par <taille>, caractèe nul compris. Le résultat est placé dans <chaine>.

● Tous les caractères supplémentaires saisis par l'utilisateur ne sont pas placés dans <chaine>,seuls les (<taille>-1) premiers caractères sont récupérés par fgets. Nous saisirons donc la phrase de notre programme de la sorte : fgets(c , 200 , stdin);

Saisie avec scanf

● scanf avec le spécificateur %s permet de lire un mot isolé à l'intérieur d'une suite de données du même ou d'un autre type.

● scanf avec le spécificateur %s lit un mot du fichier d'entrée standard stdin et le mémorise à l'adresse qui est associée à %s.

● La fonction scanf a besoin des adresses de ses arguments:
* Les noms des variables numériques (int, char, long, float, ...) doivent être marqués par le symbole '&'.
* Comme le nom d'une chaîne de caractères est le représentant de l'adresse du premier caractère de la chaîne, il ne doit pas être précédé de l'opérateur adresse '&'.
* L'utilisation de scanf pour la lecture de chaînes de caractères est seulement conseillée si on est forcé de lire un nombre fixé de mots en une fois.

Précédence alphabétique et lexicographique

● Pour le code ASCII, nous pouvons constater l'ordre suivant: ... , 0, 1 , 2, ..., 9, ..., A, B, C, ..., Z, ..., a, b, c, ..., z, ...

● Les symboles spéciaux (' ,+ ,- ,/ ,{ ,] , ...) et les lettres accentuées (é ,è ,à ,û , ...) se trouvent répartis autour des trois grands groupes de caractères (chiffres, majuscules, minuscules).

● Leur précédence ne correspond à aucune règle d'ordre spécifique.

● '0' est inférieur à 'Z' et noter '0' < 'Z'

Exemple:
● if (C>='0' && C<='9') printf("Chiffre\n");
● if (C>='A' && C<='Z') printf("Majuscule\n");
● if (C>='a' && C<='z') printf("Minuscule\n");
● Il est facile, de convertir des lettres majuscules dans des minuscules:
if (C>='A' && C<='Z') C = C-'A'+'a';
ou
if (C>='a' && C<='z') C = C-'a'+'A';

La bibliothèque "string.h"

● Cette bibliothèque propose des fonctions de maniement de chaînes de caractères, à savoir:
strlen(<s>): fournit la longueur de la chaîne sans compter le '\0' Final
strcpy(<s>, <t>): copie <t> vers <s>
strcat(<s>, <t>): ajoute <t> à la fin de <s>
strcmp(<s>, <t>): compare <s> et <t> lexico-graphiquement et retourne: -1: si <s> précède <t> | 0: si <s> est égal à <t> | 1: si <s> suit <t>
strncpy(<s>, <t>, <n>): copie au plus <n> caractères de <s> vers <t>
strncat(<s>, <t>, <n>): ajoute au plus <n> caractères de <s> à la fin de <s>
strncmp(<s>, <t>, <n>): comme strcmp mais limite la comparaison en n caractères
strcmpi(<s>, <t>): comme strcmp mais ne distingue pas les majuscules et les minuscules

Les fonctions de recherches

● strchr(chaine,caractère)
Retourne NULL si le caractère ne se trouve pas dans la chaine sinon un pointeur vers le premier caractère rouvé.
● strrchr(chaine, caractère)
Retourne NULL si le caractère ne se trouve pas dans la chaine sinon un pointeur vers le dernier caractère trouvé.
● strpbrk (chaine1,char* lettresARechercher)
Retourne NULL si aucun caractère n'est trouvé ou un pointeur sur le premier caractère trouvé.
● strrchr(chaine, caractère)
Retourne NULL si aucun caractère n'est trouvé ou un pointeur sur la première chaine trouvée.

Remarque:

La bibliothèque <stdlib> contient des déclarations de fonctions pour la conversion de nombres en chaînes de caractères et vice-versa.

● Conversion de chaînes de caractères en nombres:
atoi(<s>): retourne la valeur numérique représentée par <s> comme int
atol(<s>): retourne la valeur numérique représentée par <s> comme long
atof(<s>): retourne la valeur numérique représentée par <s> comme double

● Conversion de nombres en chaînes de caractères::
itoa (<n_int>, <s>, <b>)
ltoa (<n_long>, <s>, <b>
ultoa (<n_uns_long>, <s>, <b>)

La bibliothèque "ctype.h"

● islower(char c)
retourne une valeur différente de 0 si c est minuscule.
● isupper(char c)
retourne une valeur différente de 0 si c est majuscule.
● isdigit(char c)
retourne une valeur différente de 0 si c est un chiffre décimal ('0'..'9').
● isalpha(char c)
retourne une valeur différente de 0 si c est une lettre ('a'..'z', 'A'..'Z').
● isspace(char c)
retourne une valeur différente de 0 si c est un signe d'espacement.
● tolower(char c)
Convertit le caractère c en minuscule.
● toupper(char c)
Convertit le caractère c en majuscule.

Tableaux de CDC

● Un tableau de chaînes de caractères correspond à un tableau à deux dimensions du type char, où chaque ligne contient une chaîne de caractères.

● Exemple: char JOUR[7][9];

● Réserve l'espace en mémoire pour 7 mots contenant 9 caractères (dont 8 caractères significatifs).

Tab Demo

● Lors de la déclaration il est possible d'initialiser toutes les composantes du tableau par des chaînes de caractères constantes: char JOUR[7][9]= {"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"};

2nd emoa table