Soyez le premier à donner votre avis sur cette source.
Vue 8 358 fois - Téléchargée 916 fois
{----------------------------------------------------------------------------- Unit Name: ChiffresEnLettres Author: delphiprog Purpose: convertir un nombre entier en toutes lettres en utilisant la récursivité. La fonction Int2Letters n'est pas transposable dans d'autres langues car elle tient compte des particularités grammaticales de la langue française uniquement. C'est aussi l'occasion d'utiliser la surcharge de fonctions, disponible depuis Delphi 5 ou 6. History: 02/05/2003 publication sur DelphiFr.com -----------------------------------------------------------------------------} unit ChiffresEnLettres; interface {La fonction Int2Letters reçoit un nombre sous forme de chaine et renvoie son équivalent sous forme littérale. Exemple : Var S : string; begin S := '1971'; S := Int2Letters(S); ShowMessage(S); //-> mille neuf cent soixante et onze end;} function Int2Letters(const ANumber: string): string;overload; {La fonction Int2Letters reçoit un paramètre sous forme d'entier et renvoie son équivalent sous forme littérale. Attention, seuls les entiers de 4 chiffres maximum seront autorisés.} function Int2Letters(const ANumber: integer):string;overload; implementation uses SysUtils; const Chiffres: array['0'..'9'] of string = ('', 'un ', 'deux ', 'trois ', 'quatre ', 'cinq ', 'six ', 'sept ', 'huit ', 'neuf '); LaDizaine: array['0'..'9'] of string = ('dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf'); Dizaines: array['0'..'9'] of string = ('', 'dix ', 'vingt ', 'trente ', 'quarante ', 'cinquante ', 'soixante ', 'soixante ', 'quatre vingt ', 'quatre vingt dix '); function Int2Letters(const ANumber: string): string; var Verif: integer; Temp: string; begin Verif := StrToIntDef(ANumber, -1); if Verif = -1 then Result := Format('%s n''est pas un Chiffres valide', [ANumber]) else case Length(ANumber) of 4: //Traitement des milliers begin case ANumber[1] of '1': Result := 'mille '; else Result := Chiffres[ANumber[1]] + 'mille '; end; Temp := Copy(Anumber, 2, 3); Result := Result + Int2Letters(Temp); end; //Fin Traitement des milliers 3: //Traitement des centaines begin case Anumber[1] of '0': Result := EmptyStr; '1': Result := 'cent '; else Result := Chiffres[ANumber[1]] + 'cent '; end; Temp := Copy(ANumber, 2, 2); Result := Result + Int2Letters(Temp); end; //Fin Traitement des centaines 2: //Traitement des dizaines begin case ANumber[1] of '0': begin Result := EmptyStr; Temp := Copy(Anumber, 2, 1); Result := Int2Letters(Temp); end; '1': case ANumber[2] of '1'..'6': Result := LaDizaine[ANumber[2]]; else begin Temp := Copy(Anumber, 2, 1); Result := 'dix ' + Int2Letters(Temp); end; end; '2'..'6' : case ANumber[2] of '0': Result := Dizaines[ANumber[1]]; '1': begin Result := Dizaines[ANumber[1]] + 'et '; Temp := ANumber[2]; Result := Result + Int2Letters(Temp); end; else begin Result := Dizaines[ANumber[1]]; Temp := ANumber[2]; Result := Result + Int2Letters(Temp); end; end; '7': begin case ANumber[2] of '1': Result := Dizaines[ANumber[1]] + 'et '; else Result := Dizaines[ANumber[1]]; end; Result := Result + LaDizaine[ANumber[2]]; end; '8': begin Result := Dizaines[ANumber[1]]; Temp := ANumber[2]; Result := Result + Int2Letters(Temp); end; '9': case ANumber[2] of '0': Result := Dizaines[ANumber[1]]; else begin Result := Dizaines[pred(ANumber[1])]; Result := Result + LaDizaine[ANumber[2]]; end; end; end; end; //Fin Traitement des dizaines 1: //Traitement des unités Result := Chiffres[ANumber[1]]; else Result := 'Chiffres trop grand : 4 chiffres maximum autorisés'; end; {case Length(ANumber)} end; function Int2Letters(const ANumber: integer):string; begin Result := Int2Letters(IntToStr(ANumber)); end; end.
7 mai 2003 à 16:36
Voici un ptit corrigé (sans les règles grammaticales qui ne sont pas utiles pour etablir un cheque valide).
Function IntToFrench(value:Longint):string;
const Unite : array[0..9] of string=
('Zero','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','soixante','quatre-vinght','quatre-vingt');
Langage='Francais France';
{const Unite : array[0..9] of string= // pour la belgique
('Zero','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','septante','quatre-vinght','nonante');
Langage='Francais Belgique';}
var fr : String;
ch : String;
t : String;
begin
fr:='';
ch:=inttostr(value);
while length(ch)>0 do
begin
t:=ch[1];
case length(ch) of
2,5,8:
begin
t:=t+ch[2];
if ((Strtoint(t) in [70..79]) or (Strtoint(t) in [90..99])) and (Langage='Francais France') then
begin
fr:=fr+Dixaine[strtoint(t[1])]+' ';
t:=Inttostr((Strtoint(t)-((strtoint(t[1])*10))+10));
end;
if strtoint(t)<20 then
begin
fr:=fr+unite2[strtoint(t)-10]+' ';
delete(ch,1,1);
end
else
fr:=fr+Dixaine[strtoint(t[1])]+' ';
end;
1,3,4,6,7,9,10:
if not ((length(ch) in [3,6,9]) and(t[1]='1')) then
begin
if length(ch)=1 then
fr:=fr+unite[strtoint(t)]
else
fr:=fr+unite[strtoint(t)]+' ';
end;
end;
delete(ch,1,1);
if length(ch)=0 then break;
case length(ch) of
9 :fr:=fr+'milliard ';
6 :fr:=fr+'million ';
3 :fr:=fr+'mille ';
2,5,8 :fr:=fr+'cent ';
end;
if (strtoint(ch)=0) then
begin
case length(ch) of
4,5 :Fr:=Fr+'mille';
7,8 :Fr:=Fr+'Million';
10 :Fr:=Fr+'Milliard';
end;
break;
end;
end;
fr:=trim(fr);
fr[1]:=uppercase(fr[1])[1];
result:=fr;
end;
Bon coding ....
ManChesTer.
6 mai 2003 à 16:04
J'espère néanmoins que je n'ai pas eu l'air de dire "bah, tu vois, c'est trop facile, t'as qu'a rajouter ça et ça marche impec". J'en serais désolé :-{
J'ai fait ce truc plutôt genre "tiens, je fais le point sur ce que je sais faire avec les routines de gestion de chaîne", sans trop savoir au départ si j'arriverais quelque part... d'où un espèce de débordement enthousiaste.
Amitiés Delphistes :-D
6 mai 2003 à 14:30
Mais plutôt que l'enrobage (l'encapsulation a un autre sens), il serait mieux de l'intéger et de déclarer ta fonction à l'intérieur de la fonction Int2Letters, et de n'y faire appel que dans les cas nécessaires.
Mais on peut utiliser d'autres techniques encore plus performantes. Non pas que la tienne ne le soit pas, mais les comparaisons de chaînes de caractères sont toujours consommatrices de temps de traitement.
Rendez-vous dans quelques temps pour une copie corrigée et complétée...
Merci à tous les trois pour vos remarques constructives.
6 mai 2003 à 11:17
Je l'ai tout récemment installé, sous D4, sans trop y croire, ben ça marche du tonnerre de Brest...
Me reste plus qu'à essayer de tout comprendre ;-)
Voilà, je vais passer pour un forcené, mais ça me démangeait :
En réponse à l'inquiétude bien légitime de Nono40 quant au respect strict de certaines règles grammaticales concernant l'accord au pluriel de "vingt" et de "cent", j'ai pondu une petite fonction qui prend ça en charge. J'en ris encore :-)))))
function Ortho(A_Verifier: String): String;
begin
if Pos('quatre vingt', A_Verifier) <> 0 then
begin
if Length(A_Verifier) - Pos('quatre vingt', A_Verifier) = 12 then
Insert('s', A_Verifier, Pos('quatre vingt', A_Verifier) + 12);
end else
if Pos('cent', A_Verifier) > 1 then
begin
if Length(A_Verifier) - Pos('cent', A_Verifier) = 4 then
Insert('s', A_Verifier, Pos('cent', A_Verifier) + 4);
end;
Result := A_Verifier;
end;
Ca fonctionne très bien avec ta fonction, Delphiprog. Il suffit de l'encapsuler ainsi :
Ortho(Int2Letters(LeNombre));
Il faut éventuellement l'adapter pour qu'elle fonctionne avec un autre programme similaire, mais le principe me semble cohérent...
Bonne Prog !
5 mai 2003 à 20:40
Si je n'ai pas fait les accords que nous a indiqués Nono40, en revanche les particularités de la langue française que tu mentionnes sont bien prises en compte. C'est surement ce qui explique un code un peu plus long.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.