• Aucun résultat trouvé

Les fonctions de recherche dans une chaîne

Dans le document Programmer en langage C (Page 171-174)

On trouve, en langage C, des fonctions classiques de recherche de l’occurrence dans une chaîne d’un caractère ou d’une autre chaîne (nommée alors sous-chaîne). Elles fournissent comme résultat un pointeur de type char* sur l’information cherchée en cas de succès, et le pointeur nul dans le cas contraire. Voici les principales.

strchr ( chaîne, caractère ) (string.h)

recherche, dans chaîne, la première position où apparaît le caractère mentionné.

strrchr ( chaîne, caractère ) (string.h)

réalise le même traitement que strchr, mais en explorant la chaîne concernée à partir de la fin. Elle fournit donc la dernière occurrence du caractère mentionné.

strstr ( chaîne, sous-chaîne ) (string.h)

recherche, dans chaîne, la première occurrence complète de la sous-chaîne mentionnée.

9 Les fonctions de conversion

9.1 Conversion d’une chaîne en valeurs numériques

Il existe trois fonctions permettant de convertir une chaîne de caractères en une valeur numérique de type int, long ou double. Ces fonctions ignorent les éventuels espaces de début de chaîne et, à l’image de ce que font les codes de format %d, %ld et %f, utilisent les caractères suivants pour fabriquer une valeur numérique. Le premier caractère invalide arrête l’exploration. En revanche, ici, si aucun caractère n’est exploitable, ces fonctions fournissent un résultat nul.

atoi ( chaîne ) (stdlib.h) fournit un résultat de type int.

Fonctions de recopie de chaînes : strcpy et strncpy (suite)

donnez un mot : bon bon

_______

donnez un mot : bonjour bonjouxxxxxxxxxxxxx

atol ( chaîne ) (stdlib.h)

fournit un résultat de type long.

atof ( chaîne ) (stdlib.h)

fournit un résultat de type double.

Notez que ces fonctions effectuent le même travail que sscanf appliquée à une seule variable, avec le code de format approprié. Par exemple (si n est de type int et adr de type char *) :

n = atoi (adr) ; fait la même chose que :

sscanf (adr, "%d", &n) ;

9.2 Conversion de valeurs numériques en chaîne

La norme ne prévoit pas de fonctions de conversion d’une valeur numérique en chaîne, c’est-à-dire de fonctions jouant le rôle symétrique des fonctions atoi, atol, atof et atod. En revanche, elle prévoit une fonction sprintf, symétrique de sscanf. Elle permet de conver-tir en chaîne une succession de valeurs numériques, en y incorporant, le cas échéant, d’autres caractères. Par exemple, si n, de type int, contient 15 et si p, de type float, contient 785.35 et si tab est un tableau de caractères de taille suffisante, l’instruction suivante :

sprintf (tab, "%d articles coutent %f8.2 F", n, p) ;

placera dans tab, la chaîne suivante (elle sera bien terminée par un caractère \0) : 15 articles coutent 785.35 F

10 Quelques précautions à prendre avec les chaînes

Dans ce chapitre, nous avons examiné bon nombre des conséquences de la manière artificielle dont le langage C gère les chaînes. Cependant, par souci de clarté, nous nous sommes limité aux situations les plus courantes. Voici ici quelques compléments d’information concernant des situations moins usitées mais dont la méconnaissance peut nuire à la bonne mise au point des programmes.

10.1 Une chaîne possède une vraie fin, mais pas de vrai début

Comme nous l’avons vu, il existe effectivement une convention de représentation de la fin d’une chaîne ; en revanche, rien de comparable n’est prévu pour son début. En fait, toute adresse de type char* peut toujours faire office d’adresse de début de chaîne.

Par exemple, avec cette déclaration : char * adr = "bonjour" ; une expression telle que :

strlen (adr+2)

serait acceptée : elle aurait pour valeur 5 (longueur de la chaîne commençant en adr+2).

De même, dans l’exemple de programme du paragraphe 5.1, il serait tout à fait possible de remplacer :

strcat (ch1, ch2) ; par :

strcat (ch1, ch2+4) ;

Le programme afficherait alors simplement : bonjoursieur

Plus curieusement, si l’on remplace cette fois cette même instruction par : strcat (ch1+2, ch2) ;

on obtiendra le même résultat qu’avec le programme initial (bonjourmonsieur) puisque ch2 sera toujours concaténée à partir du même 0 de fin !

En revanche, avec :

strcat (ch1+10, ch2) ;

les choses seraient nettement catastrophiques : on viendrait écraser un emplacement situé en dehors de la chaîne d’adresse ch1.

10.2 Les risques de modification des chaînes constantes

Nous avons vu que, dans une instruction telle que : char * adr = "bonjour" ;

le compilateur remplace la notation "bonjour" par l’adresse d’un emplacement dans lequel il a rangé la succession de caractères voulus.

Dans ces conditions, on peut se demander ce qui va se produire si l’on tente de modifier l’un de ces caractères par une banale affectation telle que :

*adr = 'x' ; /* bonjour va-t-il se transformer en xonjour ? */

* (adr+2) = 'x' ; /* bonjour va-t-il se transformer en boxjour ? */

A priori, la norme interdit la modification de quelque chose de constant. En pratique, beau-coup de compilateurs l’acceptent, de sorte que l’on aboutit à la modification de notre constante bonjour en xonjour ou boxjour ! Nous pourrions, par exemple, le constater en exécutant une instruction telle que puts (adr).

Signalons qu’une constante chaîne apparaît également dans une instruction telle que : printf ("bonjour") ;

Ici, on pourrait penser que sa modification n’est guère possible puisque nous n’avons pas accès à son adresse. Cependant, lorsque cette même constante (bonjour) apparaît en plu-sieurs emplacements d’un programme, certains compilateurs peuvent ne la créer qu’une fois ; dans ces conditions, la chaîne transmise à printf peut très bien se trouver modifiée par le processus décrit précédemment...

D

ans une déclaration telle que : char ch[20] = "bonjour" ;

il n’apparaît pas de chaîne constante, et ceci malgré la notation employée ("...") laquelle, ici, n’est qu’une facilité d’écriture remplaçant l’initialisation des premiers caractères du tableau ch. En particulier, toute modification de l’un des éléments de ch, par une instruction telle que :

* (ch + 3) = 'x' ;

est parfaitement licite (nous n’avons aucune raison de vouloir que le contenu du tableau ch reste constant).

Dans le document Programmer en langage C (Page 171-174)