Objectif : Effectuer la saisie de 2 entiers et n'autoriser le calcul de leur somme et de leur produit que lorsque les 2 entiers sont entrés, la sécurité sur les données est effectuée au premier niveau par "plan d'action"et au second niveau par filtrage des saisies à travers un analyseur syntaxique .
Le graphe événementiel associé à l'énoncé
La fiche principale, le code associé dans la unit
Exécuter
le programme
La fiche principale du projet :
Remonter
Le graphe
événementiel :
L'analyseur pour le filtrage des saisies :
Un automate d'états finis (AEFD) va servir à implanter le filtrage, voici les diagrammes syntaxiques de la grammaire des mots à analyser (des nombres) :
Principe de l'AEFD retenu: l'utilisateur tape des caractères au clavier dans un Edit, tantque le caractère tapé est valide (dans 0...9) on le saisie, dans le cas contraire ce caractère n'est pas retenu.
Le code de la Unit fiche principale :
unit UFcalcul;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
ButtonCalcul: TButton;
Label1: TLabel;
Label2: TLabel;
Bevel1: TBevel;
LabelSomme: TLabel;
LabelProduit: TLabel;
Label3: TLabel;
Label4: TLabel;
Buttoneffacer: TButton;
Label5: TLabel;
procedure FormCreate(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure Edit2Change(Sender: TObject);
procedure ButtonCalculClick(Sender: TObject);
procedure ButtoneffacerClick(Sender: TObject);
private
{ Déclarations privées
}
public
{ Déclarations publiques
}
end;
var
Form1: TForm1;
Som_ok,Prod_ok:boolean;
implementation
// les erreurs de conversion ne sont pas gérées,
on utilisera plus tard
// les exceptions pour effectuer ce traitement.
{$R *.DFM}
{------------------- Utilitaires de service
-------------------}
procedure TestEntrees;
{les 2 drapeaux sont-ils levés}
begin
if Prod_ok and Som_ok then
Form1.ButtonCalcul.enabled:=true //
si oui: le bouton calcul est activé
end;
procedure RAZTout;
begin
with Form1 do
begin
Buttoneffacer.enabled:=false;
//
le bouton effacer se désactive
ButtonCalcul.enabled:=false; //
le bouton calcul se désactive
LabelSomme.caption:='0';
LabelProduit.caption:='0';
Edit1.clear;
Edit2.clear;
Prod_ok:=false;
Som_ok:=false;
end
end;
{---------------------------------------------------------------}
procedure TForm1.FormCreate(Sender: TObject);
begin
RAZTout;
end;
// les plans d'action sont matérialisés
par l'événement OnChange de Edit1 et Edit2
// le filtrage est effectué grâce
à une procédure d'automate d'états finis dénommée
"Filtrage"
procedure Filtrage(entree
:string;var resultat:string);
var i:integer;
saisie :string;
CarValides:set of char;
begin
CarValides:=['0'..'9'];
saisie:=entree;
if length(saisie)<>0 then
begin
i:=1;
while saisie[i] in CarValides do i:=i+1;
//
le premier car non juste
if not(saisie[i] in CarValides)then
delete(saisie,i,1);
end;
resultat:=saisie
end;
procedure TForm1.Edit1Change(Sender: TObject);
// les 2 niveaux de sécurité
sont combinés
var sortie:string;
begin
Filtrage(Edit1.text,sortie);
Edit1.text:=sortie;
if Edit1.text<>'' then
begin
Som_ok:=true; // drapeau de Edit1 levé
TestEntrees; // permet de rentrer
les entiers dans un ordre quelconque
end
else
begin
ButtonCalcul.enabled:=false;
Som_ok:=false; // drapeau de
Edit1 baissé
end
end;
procedure TForm1.Edit2Change(Sender: TObject);
// les 2 niveaux de sécurité
sont combinés
var sortie:string;
begin
Filtrage(Edit2.text,sortie);
Edit2.text:=sortie;
if Edit2.text<>'' then
begin
Prod_ok:=true; // drapeau de Edit2
levé
TestEntrees; // permet de rentrer
les entiers dans un ordre quelconque
end
else
begin
ButtonCalcul.enabled:=false;
Prod_ok:=false; // drapeau de
Edit2 baissé
end
end;
procedure TForm1.ButtonCalculClick(Sender: TObject);
var S,P:integer;
begin
S:=strtoint(edit1.text);
P:=strtoint(edit2.text);
LabelSomme.caption:=inttostr(P+S);
LabelProduit.caption:=inttostr(P*S);
Buttoneffacer.enabled:=true
// le bouton effacer est activé
end;
procedure TForm1.ButtoneffacerClick(Sender: TObject);
begin
RAZTout;
end;