Entrées et sorties en Pascal

Un article de Mangue.org, l'encyclopéde libre.


Voyons maintenant comment effectuer des entrées/sorties (input/output) dans nos programmes. Ceci nous permettra d'échanger des données avec l'utilisateur.
Dans ce cours, nous ne ferrons que des entrées/sorties en passant par le moniteur et le clavier, nous verrons plus tard comment utiliser des fichiers ou l'imprimante.


Sommaire

Les entrées

Dans le cours précédent vous avez déjà rencontré l'instruction readln. Celle ci stopait momentannément le programme et attendait que l'utilisateur entre une valeur suivie d'une pression sur la touche entrée.

program Lecture_caractere;

(* uses WinCrt; *)

var Lettre : char;

begin
  write ('Entrez un caractere : ');
  readln ( Lettre);
  writeln ( 'Vous avez entre : ', Lettre);
  write ('Entrez plusieurs caracterres : ');
  readln ( Lettre);
  writeln ( chr(10), chr(13)); (* nouvelle ligne *)
  (* on saute donc 2 lignes ! *)

  writeln ('Le premier est : ', Lettre);
end.

En exécutant le programme ci dessus, vous vous appercevez que si on entre plus de valeurs que ce qui est demandé (ici on ne veut q'un caractère), le compilateur prend seulement ce qui l'intéresse et ne s'occupe pas du reste.
Très souvent nous aurons besoin de demander plusieurs renseignements à l'utilisateur. Rassurez vous l'instruction readln peut évidemment prendre plusieurs arguments comme dans l'exemple qui suit avec deux caractères et un nombre

program Lettre_Entier;

(* uses WinCrt; *)

var Lettre1 : char;
    Lettre2 : char;
    Nombre  : integer;

begin
  write ('Entrez deux caracteres puis un nombre entier : ');
  readln ( Lettre1, Lettre2, Nombre);

  writeln ('Premiere caractere : ', Lettre1);
  writeln ('Second caractere : ', Lettre2);
  writeln ('Nombre entier : ', Nombre, chr(10), chr(13));
end.

Vous avez du vous en appercevoir en faisant vos essais, il est impossible de séparer les caractères et le nombre par un espace ou quoi que ce soit d'autre. Si vous le faisiez, l'espace après le premier caractère serait justement interprété comme le second caractère.
En revanche avec l'instruction readln vous pouvez séparer les différentes valeurs à entrer par des pressions sur la touche entrée.

Vous vous en doutez il existe aussi une procédure read. Elle fonctionne un peu différemment de readln dans la mesure où elle essai d'affecter une valeur à tous ses arguments dès la première pression sur entrée ; ce qui est moins pratique pour le programmeur qui devrait protéger son programme d'éventuelles erreurs ou encore pour l'usager qui doit savoir exactement quoi entrer et ne pas dse tromper.
Vous l'avez compris, dans la mesure du possible nous préfèrerons l'utilisation de readln, mais certains programmes nécessiteront l'utilisation de read ;)


Utilisation de read et readln

Les instructions read et readln ne lisent pas ce que vous entrez au clavier au fur et à mesure. Elles utilisent un tampon clavier, sorte de mémoire temporaire, qui est actualisé à chaque pression sur la touche entrée. Ensuite le compilateur traite les caractères de ce tampon les uns après les autres et essai de les typer pour les affecter aux variables que vous avez passé en argument.

Pour des caractères le compilateur prends le premier disponible dans le tampon clavier. Pour une chaîne de caractères il affecte tout le tampon à la chaîne de caractères. Si la chaîne en question a une longueur maximale fixée alors tous ceux qui vuivent sont simplement abandonnés par le compilateur.

Pour des nombres entiers et bien rien n'est très compliqué, la suite de chiffre précédée ou non du signe - est affectée à cette variable. Attention toutefois puisque des valeurs entières peuvent être affectées à des nombres réels (contrairement à d'autres langages comme le Caml ou l'Ada)

Astuce
Vous avez vu dans le [./cours5.htm cours précédent] que readln; sans aucun argument pouvait être utilisée tout simplement pour provoquer une pause au sein d'un programme. En effet celui-ci s'arrête jusqu'à la prochaine pression sur la touche entrée.


Les sorties

Vous avez déjà vu apparraître ces procédures dans tous les exemples des cours précédents, et vous n'avez pas fini de les voir !
Vous savez déjà que les procédures write et writeln peuvent admettre plusieurs arguments (voire aucun!), enfin voici un programme résumant tout ce que nous savons déjà sur les entrées/sorties :

program Entrees_Sorties;
(* bilan de ce que nous savons *)

(* uses WinCrt; *)


(* definition des constantes a afficher *)
const StrConst   = 'Une chaine de caracteres';
      IntConst   = 81;
      FloatConst = 12.0;
      ChConst    = 'ß';

(* constante interne au programme *)
const Longueur = 63;

(* declaration des variables *)
var  StrVar   : string[Longueur];
     IntVar   : integer;
     FloatVar : real;
     ChVar    : char;


(**** Debut du programme ****)

begin
  writeln ('Ecriture de constantes :');
  writeln;

  writeln ('Chaine    : ', StrConst);
  writeln ('Entier    : ', IntConst);
  writeln ('Reel      : ', FloatConst);
  writeln ('Caractere : ', ChConst);

  writeln ( chr(10),chr(13), 'Lecture des variables :');
  writeln;

  write ('Chaine    : '); readln (StrVar);
  write ('Entier    : '); readln (IntVar);
  write ('Reel      : '); readln (FloatVar);
  write ('Caractere : '); readln (ChVar);

  writeln ( chr(10),chr(13),'Ecriture de variables :');
  writeln;

  writeln ('Chaine    : ', StrVar);
  writeln ('Entier    : ', IntVar);
  writeln ('Reel      : ', FloatVar);
  writeln ('Caractere : ', ChVar);

  writeln ( chr(10),chr(13),'D''autres constantes : ');
  writeln;

  writeln ('Entier    : ', 12+15);
  writeln ('Reel      : ', 1e-3);
  writeln ('Caractere : ', chr(65));

  readln; (* pause en fin de programme *)
end.

Dans ce programme il y a deux const qui apparaîssent mais si ça vous dérange vous pouvez tout rassembler au sein de la même instruction évidemment.
De même nous voyons apparraître sur la même ligne deux instructions, nous avons vu dans le [./cours3.htm troisième cours] que c'est possible.


Formater les sorties

Formater les sorties signifie qu'on désire leur imposer un format d'affichage. Jusqu'à présent nous avons laissé le compilateur gérer ça lui même.
Essayez de comprendre vous même à quoi servent les : dans ce programme avant que je ne vous l'explique moi même ;)

program Formater_Sorties;
(* impose un format d'affichage *)

(* uses WinCrt; *)

(* constantes a afficher *)
const Entier1 = 63;
      Entier2 = -10643;
      Reel1   = 12.0;
      Reel2   = 1.23456e-3;
      Booleen = false;
      Char1   = 'B';
      Char2   = 'g';


(**** Debut du programme ****)

begin
  writeln ('Test sur les entiers...');
  writeln ( Entier1:2, Entier2:2);
  writeln ( Entier1:3, Entier2:3);
  writeln ( Entier1:5, Entier2:5);
  writeln ( Entier1:4, Entier2:8);
  writeln ( Entier1:4, Entier2);

  writeln;
  writeln ('Test sur les caracteres...');
  writeln ( Char1:2, Char2:4);
  writeln ( Char1:3, Char2:3);

  writeln;
  writeln ('Test sur un booleen...');
  writeln ( Booleen:2);
  writeln ( Booleen:5);
  writeln ( Booleen:12);

  writeln;
  writeln ( 'Test sur les flottants...');
  writeln ( Reel1:5, Reel2:12);
  writeln ( Reel1:5:0, Reel2:8:3);
  writeln ( Reel1:2:0, Reel2:9:6);
  writeln ( Reel1:3:1, Reel2:4:1);

  readln; (* pause *)
end.

Réponse
Peut-être l'avez vous deviné, ceux-cis servent à préciser le nombre de caractères sur lesquels la sortie doit être affichée. L'instruction write (EntierTest:4); demande par exemple d'afficher la valeur de EntierTest sur 4 caractères.

Lorsque le nombre de caractères que l'on précise pour l'affichage est supérieur ou égal à ce qui est requis, la valeur est affichée en étant justifiée à droite sur ce nombre de caractères.
En revanche si on fournit un nombre de caractères inférieur à ce qui est requis pour l'affichage alors le compilateur n'en tient pas compte et affiche le résultat sur un nombre correct de caractères.

Pour les nombres réels la syntaxe est étendue puisque nous voyons apparaître un second : également suivi d'un nombre. La première séquence a la même signification qu'avec les entiers par exemple, ainsi write (NombreReel:4); provoquera l'affichage de ce nombre sur 4 caractères (si c'est possible).
La seconde séquence précise le nombre de décimales que nous désirons afficher pour le nombre en question. Si vous ne précisez pas le nombre de décimales alors le compilateur optera certainement pour la notation exponentielle.

Pour prendre conscience de toutes ces nouvelles notions, je vous invite à écrire le plus de programmes possibles en effectuant vous même les modifications ;)
Voici un exemple qui vous montre l'utilité de limiter le nombre de décimales :

program ConvertionFrancEuro;

(* uses WinCrt; *)

(* declaration des constantes *)
const Affichage = 8; (* nombres affiches sur 8 caracteres *)
      Precision = 2; (* 2 decimales *)
      Change    = 6.55957;

(* declaration des variables *)
var PrixFranc, PrixEuro : real;

begin
  write ('Entrez un prix en Francs : ');
  readln ( PrixFranc);

  write ('Entrez un prix en Euros : ');
  readln ( PrixEuro);

  writeln; (* saute une ligne *)

  write ( PrixFranc:Affichage:Precision);
  writeln ( 'F = ', (PrixFranc/Change):Affichage:Precision, 'E');

  write ( PrixEuro:Affichage:Precision);
  writeln ( 'E = ', (PrixEuro*Change):Affichage:Precision, 'F');

  readln; (* pause *)
end.


Exercice

Je vous propose d'écrire un programme très simple. Celui-ci demande deux nombres entiers à l'utilisateur puis en fait la somme.
Ah ah, vous riez déjà ? Attention, vous devez faire en sorte que le résultat soit présenté comme ci c'était un enfant qui avait fait l'addition lui même, c'est à dire que les deux nombres doivent être écrits l'un en dessous de l'autre avec les unités sur la même colonne et également alligné avec le résultat comme ceci :

Entrez le premier entier : 1536
Entrez le second entier  : 537

   1536
+   537
-------
   2073

Pour des raisons de simplification dans un premier temps nous ne traiterons que des entiers positifs. Si vous n'y parvenez n'hésitez pas à poser vos questions.

Outils personels