Writeln, Readln

Résolu
cs_Kenavo Messages postés 702 Date d'inscription vendredi 21 mars 2003 Statut Membre Dernière intervention 1 octobre 2009 - 13 sept. 2004 à 18:21
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 - 14 sept. 2004 à 09:04
Aviez-vous remarqué ?
Lorsqu'on utilise les fonctions Writeln et Readln avec des variables réelles, quelque soit la config des paramètres régionaux de votre ordi, c'est toujours le '.' (point) qui est utilisé comme séparateur décimal.
J'ai remarqué ça en créant un fichier texte (TextFile) pour collecter des mesures :
Writeln(F,Now,#9,Mesure1,#9,Mesure2,#9,Mesure3);
Après, en relisant les résultats avec Excel, pas de Pb sur un ordi configuré avec le point décimal, mais sur un ordi configuré "à la française" avec virgule décimale, Excel ne reconnait pas des nombres mais du texte !
Il faut donc écrire :
Writeln(F,Now,#9,FormatFloat("0.000",Mesure1),#9,.....);
en utilisant la fonction FormatFloat (ou FloatToStrF) qui convertit un réel en chaîne en respectant la config de votre ordinateur.

Pour lire La fonction Readln est bien pratique
Realn(F,Mesure1,Mesure2,Mesure3);
permet le lire directement 3 réels dans une ligne.
Là j'ai pas trouvé d'autre solution que lire un chaîne, la découper en sous-chaînes, et les convertir une à une avec la fonction StrToFloat.

Moralité : soyez prudents si vous voulez enregistrer (ou lire) des réels dans un fichier texte, en respectant la config régionale de votre ordi (et de celui de vos voisins). Les fonctions Readln et Writeln remontent au temps(que les moins de vingt ans ne peuvent pas connaître) du DOS.
Il n'était pas question à l'époque d'utiliser autre chose que le point décimal.

Avez vous remarqué d'autres problèmes du même genre ?
Est-ce que ça a été corrigé dans les versions de Delphi plus récentes (après Delphi 4) ?

Ken@vo
____________________
Code, Code, Codec !
A voir également:

3 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
13 sept. 2004 à 18:51
Et en affectant une valeur à Application.DecimalSeparator, cela ne change rien au problème. Delphi inscrit les valeurs en utilisant le séparateur décimal défini au niveau du système.

NB : la fonction WriteLn permet de formater directement des nombres, exemple :
  WriteLn(F, Nombre1:4:2)

Formate Nombre1 sur quatre chiffres dont deux décimales.

Malheureusement, cette particularité n'est pas mentionnée dans l'aide en ligne.

Allez, un petit exemple pour s'en convaincre ?
procedure TForm1.Button2Click(Sender: TObject);
var
  F: TextFile;
  Nombre1, Nombre2: double;
begin
  Nombre1 := Random(1000);
  Nombre2 := Random(1000);

  AssignFile(F, 'Test.txt');
  Rewrite(F);
  WriteLn(F, Nombre1:4:2, #9, Nombre2:4:2);
  CloseFile(F);
  Memo1.Lines.LoadFromFile('Test.txt');
end;


C'est moins lourd à écrire et plus efficace puisque WriteLn est une fonction native du langage Pascal.
3
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
14 sept. 2004 à 09:04
Delphiprog a écrit : "Malheureusement, cette particularité n'est pas mentionnée dans l'aide en ligne.".
Cette affirmation est erronnée.
Vous en trouverez tous les détails avec l'instruction Write, toujours dans l'aide en ligne. :blush)

Kenavo a écrit : "Pour justifier à gauche on peut écrire : Writeln(F,pi:0:4);
"
/!\ Cette particularité est bien pour un affichage. Utilisée pour l'écriture dans un fichier, cela posera des problèmes pour retrouver les valeurs au moment de la lecture, les valeurs enregistrées ayant alors des longueurs variables.
3
cs_Kenavo Messages postés 702 Date d'inscription vendredi 21 mars 2003 Statut Membre Dernière intervention 1 octobre 2009 5
14 sept. 2004 à 08:31
Salut DelphiProg,

Précision :

WriteLn(F, Nombre1:10:2)

Formate Nombre1 avec deux décimales en alignant à droite sur 10 caractères.
ex : Writeln(F,pi:10:4); écrira : ' 3.1416' (4 espaces à gauche),
Pour justifier à gauche on peut écrire : Writeln(F,pi:0:4);

Ken@vo

P.S. en suivant l'instruction Writeln en assembleur, j'ai retrouvé le point décimal (dans la procedure Str2Ext)
mov byte ptr [edi], $2E . Pas de choix donc !

____________________
Code, Code, Codec !
0
Rejoignez-nous