Trouver une ressource (Nouvelle version du moteur, plus rapide & pertinent, essayez le !)
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
FORMATTEZ VOS CHAINES DE CARACTERES GRACE A LA FONCTION FORMAT
Description
Beaucoup de monde, debutants comme initiés, connaissent peu ou mal la fonction Format.
La fonction Format permet tout simplement de formatter une chaine de caracteres grace a des specificateurs de formatage. Dans cette definition barbare, il faut comprendre que format est une fonction specialisée dans la convertion de differents type (réel, entier, pointeurs ect...) dans un texte humainement lisible.
Elle remplacerat donc parfaitement des fonctions tel que IntToStr, FloatToStr, IntToHex, que certains aiment mettre de part et d'autre dans leurs methode de convertions et qui ce soucis un minimum de l'optimisation et la claretée du code de ces dernieres.
Tutorial
____________ A) Quand utiliser Format ? ____________ A.Bis) Recomendations. ____________ B) Performances ____________ C) Déclaration de Format dans Delphi ____________ D) Qu'est-ce qu'une chaine de formatage ? ____________ E) Qu'est-ce qu'un spécificateur de format ? ____________ F) Tableau des types de spécificateurs de format ____________ G) Format flottant et séparateur décimal ____________ H) Ecriture des spécificateurs d'indice, taille etprécision ____________ Z) Conclusion
A) Quand utiliser Format ?
Utilisez format dés que vous desirez convertir une valeur en une chaine de caracteres. En effet, Format vas vous faciliter grandement la vie dans ce domaine, en remplaçant toutes les autres fonctions comme FloatToStr ou IntToStr...
Exemple (afficher les coordonnées de la souris sur le titre de la fiche en cours) : procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); begin caption := 'x: '+IntToStr(X)+' | y: '+IntToStr(Y); end;
Seras facilement remplaçable par :
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); begin caption := format('x: %d | y: %d',[X, Y]); end;
Comme vous l'avez compris, Format est LA fonction spécialisée dans le formatage valeurs vers chaine.
A.Bis) Recomendations.
- Les chaines de formatage ne sont pas compilées dans Delphi, contrairement en C et C++. Verifiez donc bien le type des specificateurs de format que vous utiliserez pour eviter les erreurs d'execution.
- Pour les concatenations de chaines courtes (string et char), il est preferable de ne pas utiliser format, mais plutot la bonne vieille methode qui est la plus rapide, par exemple :
SC := protocol+'://'+domainename+'/'; {au lieu de : SC := format('%s://%s/',[protocol,domainename]); }
B) Performances
Je vous le donne en mille, Format est plus rapide que la plupart des autres méthodes. Parlons chiffres et millisecondes, avec un bench (test de performance) tout simple : [test realisé sur un Athlon 1800+ a 1.5Ghz en parfaite condition de test]
- 1er test :
for X := 1 to 1000000 do s := 'X = ' + IntToStr(X);
Résultat : Moyenne de 945 ms presque 1 seconde.
- 2eme test :
for X := 1 to 1000000 do s := format('X = %d',[X]);
Résultat : Moyenne de 532 ms presque 1/2 seconde.
(j'ai refait ce test plusieurs fois pour etre sur et certain de ce que j'avance maintenant) Format affiche de meilleures performance et vous permettras d'optimiser correctement vos programmes, surtout sur les méthodes de conversion et d'affichage de texte.
C) Déclaration de Format dans Delphi
Format est déclarée dans l'unité SysUtils de Delphi.
(Format fait appel a FmtStr(); incluse elle aussi dans l'unité SysUtils.)
Elle se présente de cette manière :
function Format(const Format: string; const Args: array of const): string; begin FmtStr(Result, Format, Args); end;
function Format(const Format: string; const Args: array of const; const FormatSettings: TFormatSettings): string; begin FmtStr(Result, Format, Args, FormatSettings); end;
const Format correspond à la chaine de format, elle contient le texte et les spécificateurs de format de cette dernière. const Args correspond au tableau d'arguments à appliquer aux spécificateurs de format contenus dans la chaine de formatage. const FormatSettings correspond aux parametres des variables globales.
D) Qu'est-ce qu'une chaine de formatage ?
Une chaine de formatage est tout simplement une chaine qui contient d'une part du texte et d'autre part des spécificateurs de format.
E) Qu'est-ce qu'un spécificateur de format ?
Un spécificateur de format est un "marqueur" qui permet d'identifier le type et les paramètres de traitement d'un argument à formater dans une chaine de format.
Dans Delphi comme dans C++, un spécificateur de format commence toujours par le symbole "%". Il est donc logique que le caractères % (pour afficher un pourcentage par exemple) s'obtiens donc en le doublant comme ceci "%%" (a l'instar d'un double ' ' dans une chaine string). Exemple :
format('le rapport est de : %.2f %%',[rapport]);
Les spécificateurs de format ont la forme suivante : (tiré de l'aide Delphi)
"%"[index ":"]["-"][largeur]["."prec]type
Comme dit plus haut, Le spécificateur de format commence toujours par le symbole %, il sera suivis ensuite de divers paramètres (dans l'ordre) :
[index ":"] correspond a l'index de l'argument dans le tableau d'arguments (facultatif) ["-"] correspond a l'alignement par défaut a gauche (facultatif) [largeur] correspond a la taille (facultatif) ["." prec] correspond a la précision (facultatif) type correspond au type de l'argument à convertir (obligatoire) (Provoquerasune erreur de conversion si l'argument n'est pas de ce type)
Index, Largeur et Précision doivent être de type entier.
F) Tableau des types de spécificateurs de format __| %d |____________________________________________
Entiers signés.
Types supportés : integer, smallint, shortint, longint, byte, word, int64, cardinal.
Si le spécificateur de précision est défini, la chaine en sortie sera remplie de zéro si la taille de l'entier est inferieure à celle de la précision.
Exemple: format('mon chiffre est : %.4d', [12]); renvois "mon chiffre est : 0012"
__| %u |____________________________________________
Entiers non-signés. (valeur absolue)
Identique à %d mais sans retour de signe.
%u est equivalant a : format( '%d', [abs(var)]);
__| %e |____________________________________________
Réel signé. (écriture scientifique)
Types supportés : single, real, real48, double, comp, extended, currency.
La valeur est convertie en une chaîne de la forme "-d.ddd...E+ddd".
Le nombre total de chiffres dans la chaîne résultante (y compris celui qui précède la virgule) est donné par le spécificateur de précision dans la chaîne de format. Si celui-ci est omis, une précision de 15 est prise en compte par défaut.
Le caractère "E" dans la chaîne résultante esttoujours suivi d'un signe "+" ou "-", puis de trois chiffres au moins.
__| %f |____________________________________________
Réel signé.
Types supportés : single, real, real48, double, comp, extended, currency.
Définissez un spécificateur de précision pour définir le nombre de chiffres après la virgule.
Exemple : format('Pi = %.4f', [pi]); renvois "Pi = 3,1415"
format('Pi = %.0f', [pi]); renvois "Pi = 3"
__| %g |____________________________________________
Réel signé. (au plus court)
Types supportés : single, real, real48, double, comp, extended, currency.
La valeur est convertie en une chaîne décimale la plus courte possible en utilisant le format fixe ou scientifique.
Le nombre de chiffres significatifs dans la chaîne résultante est fourni par le spécificateur de précision dans la chaîne de format : une précision par défaut de 15 est prise en compte si le spécificateur de précision est omis.
Les caractères zéro sont supprimés de la fin de la chaîne résultante et la virgule décimale n'apparaît que si elle est nécessaire.
La chaîne résultante utilise le format fixe si le nombre de chiffres à gauche de la virgule est inférieur ou égal à la précision indiquée et si la valeur est supérieure ou égale à 0,00001. Sinon, la chaîne résultante fait appel au format scientifique.
__| %n |____________________________________________
Réel signé. (avec séparateur des milliers) Entier signé. (voir la note)
Types supportés : single, real, real48, double, comp, extended, currency.
Numérique L'argument doit être une valeur flottante.La valeur est convertie en une chaîne de la forme"-d,ddd,ddd.ddd...". Le format "n" correspond au format "f", sauf que la chaîne résultante contient le séparateur des milliers.
Exemple : format('%n', [10248.125]); renvois "10 248,125"
_____| NOTE |_____
Types : integer, smallint, shortint, longint, byte, word, int64, cardinal.
Pour ces types vous devrez écrire format de cette façon :
format('%.0n', [VarInt / 1]);
Exemple : format('Taille : %.0n octets', [24533126/1]); renvois "Taille : 24 533 126 octets"
__| %m |____________________________________________
Réel signé. (représentation monétaire)
Types supportés : single, real, real48, double, comp, extended, currency.
La valeur est convertie en une chaîne représentant une valeur monétaire.
La conversion est contrôlée par les variables globales CurrencyString, CurrencyFormat, NegCurrFormat,ThousandSeparator, DecimalSeparator et CurrencyDecimals ou leur équivalent dans une structure de données TFormatSettings.
Si la chaîne de format contient un spécificateur deprécision, il remplace la valeur envoyée par la variable globaleCurrencyDecimals ou son équivalent TFormatSettings.
Exemple : CurrencyString := '€'; format('Francs en Euros : %.5m', [100 / 6.55957]); renvois "Francs en Euros : 15,24490 €"
CurrencyString := 'Fr'; format('Euros en Francs : %.2m', [15.24490 * 6.55957]); renvois "Euros en Francs : 100,00 Fr"
__| %p |____________________________________________
Pointeur.
Types supportés : (^Type), PAnsiString, PString,PByteArray, PCurrency, PDouble, PExtended, PSingle, Pinteger,POleVariant, PShortString, PTextBuf, PVarRec, PVariant, PWideString, PWordArray.
La valeur est convertie en une chaîne de 8caractères (32bits) qui représente des valeurs de pointeur enhexadécimal.
Exemple : format('%p', [PInteger(1024)]); renvois "00000400"
__| %s |____________________________________________
Chaîne.
Types supportés : String, Char, PChar, AnsiString, WideString, ShortString. La chaîne ou le caractère est inséré à la place du spécificateur de format.
Définissez le spécificateur de précision pour indiquer la taille maximale de la chaine, qui sera alors tronquée automatiquement si elle est plus grande.
Exemple : format('nom : %s, prénom : %s', [edit1.text, edit2.text]); renvois "nom : Borland, prénom : Delphi" __| %x |____________________________________________
Hexadécimal.
Types supportés : integer, smallint, shortint, longint, byte, word, int64, cardinal.
La valeur est convertie en sa représentation hexadécimale.
Si la chaîne de format contient un spécificateur deprécision, ce dernier spécifie que la chaîne doit contenir au moins le nombre indiqué de chiffres; si cela n'est pas le cas, des caractères zéro de remplissage sont rajoutés dans la partie gauche de la chaîne.
Exemple : format('Char : #%0:.3d | Hexa : %0:.2x', [ord(' ')]); renvois "Char : #032 | Hexa : 20"
G) Format flottant et séparateur décimal
"Quelque soit le format flottant, les deux caractères utilisés comme séparateur décimal et séparateur des milliers sont respectivement définis par les variables globales DecimalSeparator et ThousandSeparator ou leur équivalent TFormatSettings."
Il faut comprendre par la, qu'en assignant une nouvelle valeur a ces variables globales, on peu modifier l'aspect d'affichage mais également de réceptions des valeurs de type flottant.
Un exemple concret de cette méthode est par exemple la réception d'un chiffre à virgule dans une boite d'édition (TEdit). L'utilisateur peut soit mettre un point, soit mettre une virgule pour définir le séparateur décimal. Afin d'éviter le declenchement d'une exception de conversion, il nous faut écrire une méthode simple pour savoir si nous sommes en présence d'un point ou d'une virgule comme séparateur de décimales. Exemple :
if pos('.',edit1.text) > 0 then DecimalSeparator := '.' else if pos(',',edit1.text) > 0 then DecimalSeparator := ',';
Cette méthode influera directement sur toutes les fonctions de conversion Flottant vers Chaine et inversement, tel Format, FloatToStr,FloatToStrDef, StrToFloat etc....
Après traitement, nous pourrons réassigner à DecimalSeparator, une valeur par défaut (virgule par exemple) et afficher les résultats en conséquence :
DecimalSeparator := ','; Label1.caption := Format('mon resultat est : %.2n',[resultat]);
H) Ecriture des spécificateurs d'indice, taille et précision
"Les spécificateurs d'indice, de taille et de précision peuvent être directement spécifiés en utilisant des chaînes contenant des chiffres décimaux (par exemple "%10d") ou indirectement, en utilisant le caractère astérisque (par exemple "%*.*f"). Lorsquevous utilisez l'astérisque, l'argument suivant dans la liste (qui doit être obligatoirement une valeur entière) devient la valeur effectivement utilisée".
Exemple :
format('%.*f',[precision, chiffre]);
Dans cet exemple, le caractère * sera remplacer par le chiffre "precision". Retenez bien cette méthode, car elle vous évitera de déclarer plusieurs constantes de chaine de format et donc permettra encore une fois d'alléger votre code.
Voici un exemple de ce qu'il ne faudrait pas faire :
Function MavaleurToStr(const val: single; const Precision: byte = 0) : string; const Precision0 := '%.0f'; Precision2 := '%.2f'; Precision4 := '%.4f'; Begin case Precision of 0 : CDF := Precision0; 1 : CDF := Precision2; 2 : CDF := Precision4; end; result := format(CDF,[val]); end;
(PS: ne rigolez pas, j'ai déjà vus ce genre de code dans des programmes pourtant sérieux. Ce qui démontre bien le manque de connaissance vis à vis de la fonction Format).
Voici maintenant la bonne version de la méthode :
Function MavaleurToStr(const val: single; const Precision: byte = 0) : string; Begin result := format('%.*f',[Precision, val]); end;
On peu bien sur utiliser "*" pour l'indice de l'argument exemple : Type TColor3h = record Red, Green, Blue : byte; end; TColorVl = (cvAll, cvRed, cvGreen, cvBlue);
Function RGBStrHex(const RGB: TColor3h; const color : TColorVl = cvAll) : string; Begin // si on ne precise pas de couleur en particulier if color <> cvAll then // on renvois la couleur selon l'indice (ord) de color dans le type TColorvl // format recupere ce chiffre comme indice dans le tableau d'arguments // et nous renvois donc la couleur desirée result := format('%*:.2x',[ord(color), RGB.Red, RGB.Green, RGB.Blue]) else // sinon, on renvois tout... result := format('%.2x%.2x%.2x',[RGB.Red, RGB.Green, RGB.Blue]) end;
Dans cette fonction, on raccourcit radicalement le code, ce qui évite de faire des cascade de IF ... ELSE ou de CASE ... OF. La méthode devient alors simple et rapide, tout cela encore, grâce à Format.
Z) Conclusion
Voila, ce tuto sur la fonction format est finit.
Vous pouvez en retenir que :
- Format est la solution la plus pratique pour convertir une valeur en une chaine de caractères.
- Format est deux fois plus rapide que les méthodes : Chaine = SousChaine + "type"ToStr(valeur).
- Format permet de réduire considérablement le code des diverses méthodes de conversion vers chaine decaractères.
- Format rentre complètement dans le cadre "optimisation" des programmes.
Historique
- 29 novembre 2005 22:48:07 :
- reglage d'un petit probleme de mise en page...
- 30 novembre 2005 14:49:52 :
- diverses corrections de fautes et presentation.
- 15 janvier 2006 03:25:00 :
- ajout du chapitre A.Bis (recomendations)
Commentaires
|
|