Manipulation de valeurs numériques à l'intérieur de chaînes de caractères
École de technologie supérieure |
|
TUTORIEL Manipulations de lecture/écriture sur des chaînes de caractères |
INF155 Introduction à la programmation |
1. "sprintf" ou comment "écrire" dans une chaîne
Problème: vous êtes en mode graphique et vous devez afficher la valeur numérique de certaines variables
Comme vous le savez, vous ne pouvez pas utiliser "printf", "puts" ou "putchar" dans ce mode. Que faire? Les fonctions "outtext" et "outtextxy" sont bien disponibles mais elles ne permettent que l'affichage de chaînes de caractères et non l'affichage de valeurs numériques.
La solution consiste donc à pouvoir insérer nos valeurs numériques dans une chaîne de caractères pour ensuite offrir cette chaîne à "outtext" ou "outtextxy". Pour ce faire, rien de plus facile. Utilisez la fonction "sprintf" qui permet "d'écrire" dans une chaîne de caractères tout ce qu'on veut.
Exemple
Voici quelques déclarations hypothétiques:
int x, y; double niveau;
Vous désirez afficher en mode graphique la valeur de vos variables entières 'x' et 'y' et la valeur de votre variable réelle 'niveau':
1. Déclarez une variable "chaîne de caractères" assez grande pour contenir votre message complet:
char msg[200];
2. Utilisez "sprintf" pour construire votre message. Cette fonction s'utilise comme "printf" sauf que le résultat de "l'écriture" est dirigé dans le premier argument plutôt qu'à l'écran :
sprintf(msg, "Mon x = %i, mon y = %i et niveau = %.2f", x, y, niveau);
3. Votre chaîne étant construite, ne reste plus qu'à l'afficher avec "outtext" ou "outtextxy":
outtext(msg);
2. Comment récupérer un nombre coincé dans une chaîne de caractères?
Vous avez lu tout plein d'information avec un "gets" ou autrement et vous voilà pris avec une longue chaîne de caractères dans laquelle vous devez récupérer des valeurs numériques.
La première chose à faire est d'utiliser les fonctions de la librairie "string.h" pour bien cerner les valeurs numériques (strtok par exemple). Ensuite, trois solutions s'offrent à vous.
A. "ssanf" ou comment "lire" dans une chaîne
Vous savez tous comme lire des nombres avec "scanf"? Et bien voici "sscanf", une fonction qui vous permet de lire des nombres qui se trouvent DANS une chaîne de caractères. Voici un exemple avec une lecture d'un nombre entier long coincé dans une chaîne:
#include <stdio.h>
int main(void){
char morceau[200];
int r;
long n;
while (gets(morceau)){
|
Je suppose ici que l'utilisateur saisit un nombre |
r = sscanf(morceau, "%li", &n);
|
récupération du "long" dans la variable "n" |
if (r == 1)
... c'est un succès
else
... c'est un échec
|
on peut tester le résultat pour vérifier si la "lecture" s'est bien passée |
}
return 0;
}
|
B. "atoi", "atol" et "atof"
La librairie "stdlib" contient trois fonctions permettant également de récupérer des valeurs numériques à partir de chaînes de caractères. Voici leur prototype:
int atoi(const char * s); long atol(const char * s); double atof(const char * s);
Ces trois fonctions retournent le nombre récupéré dans "s" si tout va bien. Dans le cas contraire, elles retournent la valeur 0. Voici un exemple avec une lecture d'un nombre entier long coincé dans une chaîne:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char morceau[200];
long n;
while (gets(morceau)){
|
Je suppose ici que l'utilisateur saisit un nombre |
n = atol(morceau);
|
récupération du "long" dans la variable "n" |
if (n)
... c'est un succès
else
... c'est un échec ou la chaîne contenait zéro
|
on peut tester le résultat pour vérifier si la "lecture" s'est bien passée |
}
return 0;
}
|
Ces trois fonctions ne permettent donc pas de faire une distinction entre l'échec et la "lecture" de la valeur zéro. C'est pourquoi on leur préfère souvent "sscanf" ou les fonctions décrites à la section C.
C. "strod", "strtol" et "strtoul"
La librairie "stdlib" contient également trois autres fonctions permettant également de récupérer des valeurs numériques à partir de chaînes de caractères. Voici leur prototype:
long strtol (const char * s, char ** ptrFin, int base); unsigned long strtoul(const char * s, char ** ptrFin, int base); double strtod (const char * s, char ** ptrFin);
Ces trois fonctions retournent le nombre récupéré dans "s" si tout va bien. Dans tous les cas, elles retournent dans le paramètre "ptrFin" un pointeur sur le premier caractère qui a stoppé la récupération. Ainsi, on peut se servir de ce pointeur pour savoir exactement où le blocage a eu lieu. Si ce pointeur vaut NUL, c'est donc dire que le nombre récupéré terminait la chaîne de caractère. Voici un exemple avec une lecture d'un nombre entier long coincé dans une chaîne:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char morceau[200];
char * ptrBlocage;
long n;
while (gets(morceau)){
|
Je suppose ici que l'utilisateur saisit un nombre |
n = strol(morceau, &ptrBlocage, 10);
|
récupération du "long" dans la variable "n" |
if (strlen(ptrBlocage) == 0))
... c'est un succès
else
... c'est un échec
|
on peut tester le pointeur retourné de diverses façon pour s'assurer du succès, tout dépend de la forme de votre chaîne. |
}
return 0;
}
|