CHIFFRES EN LETTRES ET RÉCURSIVITÉ

cs_ManChesTer Messages postés 374 Date d'inscription vendredi 20 octobre 2000 Statut Modérateur Dernière intervention 15 janvier 2021 - 3 mai 2003 à 00:47
cs_ManChesTer Messages postés 374 Date d'inscription vendredi 20 octobre 2000 Statut Modérateur Dernière intervention 15 janvier 2021 - 7 mai 2003 à 16:36
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/12515-chiffres-en-lettres-et-recursivite

cs_ManChesTer Messages postés 374 Date d'inscription vendredi 20 octobre 2000 Statut Modérateur Dernière intervention 15 janvier 2021
7 mai 2003 à 16:36
Merci Japee,

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.
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
6 mai 2003 à 16:04
Tout bien reçu 5 sur 5, Delphiprog.

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
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
6 mai 2003 à 14:30
Merci pour cette intéressante proposition.
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.
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
6 mai 2003 à 11:17
Merci à toi Delphiprog, pour ce beau bout de code !
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 !
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
5 mai 2003 à 20:40
Merci pour ces précisions Japee.
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.
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
5 mai 2003 à 18:56
Bonjour, ManChesTer

Elle est superbe, ta fonction, mais elle ne s'adapte pas bien au français.
Je m'explique :
si tu saisis (71..76), tu obtiens Soixante-dix un, Soixante-dix deux, etc..., pareil avec la suite (91..96) où tu obtiens Quatre vingt dix un, Quatre vingt dix trois, etc...
C'est normal, c'est une particularité (tordue, à mon avis...) de la langue française qui fait qu'on dit "60 et 11" pour "71", etc...
Il faudrait, pour que ça fonctionne, utiliser, comme nos amis belges et suisses francophones, les expressions "Septante" pour "Soixante-dix" et "Nonante" pour "Quatre-vingt-dix" (l'équivalent de "Seventy" et de "Ninety").

D'autre part il faudrait remplacer la constante Unite[0] qui est '' par 'zéro', ça évite de planter sur
fr[1] := uppercase(fr[1])[1]
quand on saisit "0", justement.

Enfin, ça n'a pas l'air de bien fonctionner avec les dizaines de milliers, les centaines de milliers, les dizaines de millions, les centaines de millions, quand ils sont terminés parune suite de "0", par exemple "50000", "200000", etc...

Désolé, c'est vrai qu'en plus, le français, c'est pas simple :-(
cs_ManChesTer Messages postés 374 Date d'inscription vendredi 20 octobre 2000 Statut Modérateur Dernière intervention 15 janvier 2021
3 mai 2003 à 21:39
Merci Mono40 pour les regles,
mais la routine que j'ai postèe est a la base multilingue et permet l'impression de cheques dans divers langues .....
C'est donc volontairement q'elles ne sont pas appliquèes, les regles n'etant pas internationales et etant inutiles pour faire un cheque valable.

ps:la version orgignale est capable d'ecrire "-cent vingt trois euros soixante deux cents-" dans 45 langues... (idem en USD,Yen etc....).

Bon coding...

ManChesTer.
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
3 mai 2003 à 08:25
Merci à tous les deux.
Merci à Manchester pour avoir étendu les capacités de cette fonction, même si elle n'utilise pas la récursivité. Plus simple ? c'est à chacun d'apprécier.
Merci à Nono40 de nous (me) rappeler les règles grammaticales qui me manquaient lorsque j'ai écrit ce code.
cs_Nono40 Messages postés 962 Date d'inscription mercredi 3 avril 2002 Statut Membre Dernière intervention 12 septembre 2006 2
3 mai 2003 à 02:48
Extrait : "Vingt et cent prennent la marque du pluriel quand, multipliés par autre adjectif numéral, ils forment le deuxième terme d'un adjectif numéral composé. Mais il est d'usage de ne pas mettre d's s'ils sont suivis d'un autre adjectif numéral"
En clair :
Quatre-vingts
Quatre-vingt deux
Cent
Cent quatre
Deux cents
Deux cent douze

Mille est invariable dans tous les cas.

Que celui qui pense que le Français est simple, relise son livre de grammaire...
cs_ManChesTer Messages postés 374 Date d'inscription vendredi 20 octobre 2000 Statut Modérateur Dernière intervention 15 janvier 2021
3 mai 2003 à 00:47
Voici la meme chose, en + simple...

prend en compte les milliards jusque 99 milliards mais peut facilement etre étendu .....

Function IntToFrench(value:Longint):string;
const Unite : array[0..9] of string=
('','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-dix','quatre vinght','quatre vingt dix');
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)<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
if length(ch)=1 then
fr:=fr+unite[strtoint(t)]
else
fr:=fr+unite[strtoint(t)]+' ';
end;
delete(ch,1,1);
if length(ch)=0 then break;
case length(ch) of
9 :fr:=fr+'milliards ';
6 :fr:=fr+'millions ';
3 :fr:=fr+'mille ';
2,5,8 :fr:=fr+'cent ';
end;
if (strtoint(ch)=0) then
break;
end;
fr:=trim(fr);
fr[1]:=uppercase(fr[1])[1];
result:=fr;
end;


Bon Coding....

ManChesTer.
Rejoignez-nous