
FAQ CConsultez toutes les FAQ
Nombre d'auteurs : 28, nombre de questions : 175, création le 11 janvier 2013
Sommaire→Pointeurs, tableaux et chaînes de caractères→Les chaînes de caractères- Qu'est-ce qu'une chaîne de caractères ?
- Qu'est-ce que le caractère NUL ?
- Pourquoi ce NUL est-il obligatoire en fin d'une chaîne ?
- Quelle est la différence entre 'a' et 'a' ?
- Que signifie 'char s[21] = 'Bonjour';' ?
- Que signifie 'char * p = 'Bonjour';' ?
- Comment convertir une chaîne de caractères en minuscules ?
- Comment convertir une chaîne de caractères en majuscules?
- Comment convertir un nombre en chaîne de caractères ?
- Comment convertir une chaîne de caractères en nombre ?
- Comment concaténer deux chaînes de caractères ?
- Comment comparer 2 chaînes de caractères ?
- Pourquoi la comparaison avec une chaîne lue par fgets échoue toujours ?
- Comment créer un tableau de chaînes de caractères ?
- Quel est le rôle de \ dans une chaîne de caractères ?
Une chaîne de caractères est un groupe de caractères réunis dans un ordre précis. En langage C, un caractère spécial, noté '\0', doit apparaître à la fin de toute chaîne sans quoi il serait impossible de détecter sa fin. Ainsi, en C, la chaîne "abc" par exemple est constituée de 4 caractères à savoir le caractère 'a', le caractère 'b', le caractère 'c' et enfin le caractère de fin de chaîne '\0'. Plus précisément, "abc" désigne un tableau de 4 caractères initialisé avec 'a', 'b', 'c' et '\0'.
Le caractère NUL, '\0', est le caractère dont tous les bits sont à zéro, autrement dit le caractère vallant 0.
Car il permet d'indiquer la fin de la chaîne. Quand on pointe sur une chaîne, tous les caractères qui suivent le caractère de fin de chaîne seront ignorés par les fonctions recevant en argument une chaîne de caractères.
'a' est l'expression d'un caractère tandis que "a" désigne un tableau de 2 caractères composé de deux caractères : 'a' et '\0'.
'char s[21] = "Bonjour";' crée un tableau de 21 éléments (de type char) initialisé avec la chaîne "Bonjour" ('B', 'o', 'n', 'j', 'o', 'u', 'r' et '\0'). Cette écriture est strictement équivalente à :
char s[21] = {'B', 'o', 'n', 'j', 'o', 'u', 'r', '\0'};
La fonction strcpy permet de copier une chaîne vers un autre tableau.
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[21];
strcpy(s, "Bonjour");
printf("%s\n", s);
return 0;
}
'char * p = "Bonjour";' crée un pointeur p qui pointe sur une chaîne vallant "Bonjour". L'emplacement des chaînes littérales dépend de l'environnement, le langage C ne garantit pas que cette zone soit modifiable.
char * p = "Bon*our";
p[3] = 'j'; /* Incorrect (mais accepte par le compilateur !). Il n'est pas garanti que p[3] soit modifiable. */
strcpy(p, "Salut"); /* Incorrect (mais accepte par le compilateur !). Pour la meme raison. */
p = "Salut"; /* Correct. p pointe maintenant sur une chaine de caracteres valant "Salut". */
N.B. : Pour écrire du code portable, il faut considérer que la zone est en lecture seule et il est donc conseillé de définir le pointeur en tant que pointeur sur des constantes.
char const * p = "Bon*our";
p[3] = 'j'; /* Incorrect. Immediatement rejete par le compilateur. On ne peut pas modifier une 'constante' ! */
strcpy(p, "Salut"); /* Incorrect. Immediatement rejete par le compilateur. Pour la meme raison. */
p = "Salut"; /* Correct. p pointe maintenant sur une chaine de caracteres valant "Salut". */
Il faut utiliser la fonction tolower(). Mais elle ne convertit qu'un seul caractère, il faut donc utiliser une boucle. Sous Windows on peut utiliser directement les fonctions CharLower ou CharLowerBuff qui convertissent une chaîne de caractères en minuscules.
Il faut utiliser la fonction toupper(). Mais elle ne convertit qu'un seul caractère, il faut donc utiliser une boucle. Sous Windows on peut utiliser directement les fonctions CharUpper ou CharUpperBuff qui convertissent une chaîne de caractères en majuscules.
Pour convertir un nombre en chaîne de caractères, on utilise la fonction sprintf() (déclarée dans stdio.h). Cette fonction fait partie de
la norme ANSI-C, elle peut donc être utilisée sous n'importe quelle plateforme.
Pour placer un nombre entier dans une chaîne de caractères, on procédera donc ainsi :
#include <stdio.h>
char buf[32];
int n = 10;
sprintf(buf, "%d", n);
sprintf() admet différents paramètres, comme
- %s pour une chaîne de caractères,
- %f pour un nombre réel,
- %u pour un nombre non signé,
- %x pour un nombre hexadécimal.
N.B. :la norme C99 a introduit la fonction snprintf() similaire à sprintf() dans son foncionnement mais prennant en paramètre la
taille maximale de la chaîne résultante.
La méthode la plus simple pour convertir une chaîne de caractères en nombre consiste à utiliser une des fonctions de la série atoxxx,
déclarées dans stdlib.h. Par exemple, l'appel atol("1234") permet de convertir la chaîne "1234" en long de valeur 1234.
Les fonctions de lecture formatée telles que sscanf permettent également d'arriver à ce résultat. Cependant, ces fonctions ne permettent pas une gestion avancée des erreurs.
De plus, faire une lecture formatée à l'aide de sscanf par exemple est un très mauvais choix. En effet, ce type de traitement coût cher en termes de temps d'exécution.
Cela est du aux nombreuses analyses préalables à effectuer sur la chaîne de formattage. Pour ces raisons, il est recommandé d'utiliser les fonctions de la série strtoxxx.
Le programme suivant illustre une utilisation typique de strtol pour convertir une chaîne de caractères en long.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int str_to_long(const char *s, long *p);
int main(void)
{
long n;
int ret = str_to_long("1234", &n);
if (ret == 0)
printf("n = %d\n", n);
else
printf("str_to_long a retourne le code d'erreur : %d\n", ret);
return 0;
}
int str_to_long(const char *s, long *p)
{
int ret = 0; /* code d'erreur 0 : succes. */
if (*s == '\0')
ret = 1; /* code d'erreur 1 : la chaine a convertir est vide. */
else
{
char *end;
*p = strtol(s, &end, 10);
if (errno != 0)
ret = 2; /* code d'erreur 2 : la fonction strtol a rencontre une erreur. */
else if (*end != '\0')
ret = 3; /* code d'erreur 3 : la conversion a echoue car un caractere invalide a ete detecte. */
}
return ret;
}
Pour cela, il existe plusieurs méthodes. Si on désire concaténer deux chaînes et placer le résultat dans une troisième, on peut utiliser sprintf(). Par exemple :
#include <stdio.h>
char Chaine1[32], Chaine2[32], ChaineFinale[64];
sprintf(ChaineFinale, "%s%s", Chaine1, Chaine2);
Mais on peut également utiliser la fonction strcat(). Cette fonction ne prend que deux paramètres (et non pas trois), elle ajoute la deuxième chaîne à la première. Par exemple :
#include <string.h>
char Chaine1[64], Chaine2[32];
strcat(Chaine1, Chaine2); /* Chaine1 contient maintenant Chaine1 + Chaine2 */
N.B. : pour utiliser strcat, il faut impérativement que la chaîne de destination soit initialisée avec une chaîne de caractères valide (terminée par le caractère de fin de chaîne '\0') et ait une taille suffisante pour pouvoir ajouter la seconde chaîne.
Pour comparer 2 chaînes, il ne faut pas utiliser l'opérateur == .
La fonction strcmp le permet et si l'on désire effectuer une comparaison sur une longueur donnée de la chaîne, il faut alors utiliser la fonction strncmp. A noter que la comparaison se termine lors de l'apparition de la première différence entre les 2 chaînes, ou que la fin de chaîne est atteinte.
- une valeur 0 indique que les chaînes sont identiques
- une valeur négative indique que la chaîne 1 contient des caracètres dont la valeur ASCII est inférieure à ceux de la chaîne 2
- une valeur positive indique que la chaîne 1 contient des caracètres dont la valeur ASCII est supérieure à ceux de la chaîne 2
const char * chaine1 = "blabla";
const char * chaine2 = "blabla";
const char * chaine3 = "blablu";
if (strcmp(chaine1, chaine2) == 0)
{
/* les chaines sont identiques */
}
if (strcmp(chaine2, chaine3) != 0)
{
/* les chaines sont différentes */
}
if (strncmp(chaine2, chaine3, 3) == 0)
{
/* les chaines sont identiques en se limitant a comparer les 3 premiers caracteres */
}
Lors de la lecture d'une chaîne de caractères dans un fichier via la fonction fgets(), il reste dans la chaîne le caractère de saut de ligne '\n'. Ainsi lorsque l'on compare cette chaîne lue avec une autre chaîne, qui devrait être égale, la comparaison échoue toujours. Il faut donc supprimer le caractère '\n' avant de travailler sur notre chaîne.
char s[256];
FILE * fp;
...
if (fgets(s, sizeof s, fp) != NULL)
{
char * p = strchr(s, '\n');
if (p != NULL)
*p = 0;
}
Pour cela, il faut créer un tableau à deux dimensions. Par exemple pour créer un tableau de 10 chaînes de caractères (de 256 caractères chacune), on pourra procéder ainsi :
#include <string.h>
...
char Tableau[10][256];
...
strcpy(Tableau[0], "azerty");
Dans cet exemple, on place le mot "azerty" dans la chaîne de caractères d'indice 0.
Le \ (backslash) dans une chaîne, ou dans un simple caractère, sert à annoncer une séquence spéciale. De ce fait, si vous-voulez avoir réellement le caractère backslash, vous devez écrire une séquence spéciale et non tout simplement '\'. Voici quelques séquences spéciales fréquemment utilisées :
- '\n' : "line feed" (LF) ou "nouvelle ligne". Selon le contexte ce caractère est parfois interprété tel quel et parfois interprété comme le marqueur de fin de ligne (qui n'est pas forcément LF).
- '\t' : "tabulation horizontale".
- '\r' : "carriage return" (CR) ou "retour chariot". C'est le caractère de retour en début de ligne.
- '\f' : "nouvelle page".
- '\b' : "backspace" ou "suppression arrière". Supprime le caractère qui se trouve devant lui.
- '\a' : "audible bell" ou "son audible". L'impression de ce caractère provoque un signal sonore.
- '\\' : l'antislash.
L'oubli du deuxième \ pour obtenir l'antislash dans une chaîne est source de bien d'ennuis pour les programmeurs débutants sous Windows comme le montre l'exemple suivant :
remove("c:\developpez\faqc\test.txt"); /* Ne fonctionne pas */
remove("c:\\developpez\\faqc\\test.txt"); /* Fonctionne */



