Publié : lun. 02/juin/2008 11:08
Merci a Brossden pour ce bout de code.
Pour moi, il est tres tres interressant.
Merci encore.
Pour moi, il est tres tres interressant.
Merci encore.
Forums PureBasic - Français
https://www.purebasic.fr/french/
Code : Tout sélectionner
;---------------------------------------------------------------------------------------------------------
; CODE de la : Convertir Chiffres en Lettres
; 13-06-2008 J.G. (GeBonet)
;' ---------------------------------------------------------------------------------------------------------
; Initialisation de la table des nombres à partir de lecture des DATA.... On..
; Charge dans deux tableaux qui sont :
Global Dim TableEntier.s(90) ; << Les entiers >>
Global Dim TableDecim.s(14) ; << Les décimales >>
Global Nombre.s
Global nb.s
Global Section.s
Global Decode.s
;---------------------------------------------------------------------------------------------------------------------------
; MODULES de lecture dans les tables
;
; Section.s = désigne les entiers ou les décimales
; Cle.s = désigne le numéro de la table ou se trouve la repésentation du nombre
;' --------------------------------------------------------------------------------------------------------------------------------
Procedure.s LitDansFichierLettres(Section.s, Cle.s)
Protected strReturn.s ,Indice.b
Shared TableEntier.s(), TableDecim.s(), EnLettre.s
If Section="Chiffres" : Indice=1: EndIf ; Donne une valeur d'orientation...On pourrait en nettoyant
If Section="Decimale": Indice=2:EndIf ; le programmme supprimer ici une partie de code...
strReturn = Space(255) ; par une affectation directe selon Section et Cle !
Select Indice ; rechercher la valeur donné par la Clef
Case 1
strReturn=TableEntier.s(Val(Cle)) ; C'est la partie entière
Case 2
strReturn=TableDecim.s(Val(Cle)) ; C'est la partie décimale
Default
strReturn="Erreur Table"
Return
EndSelect
Position=FindString(strReturn, "=",1)
EnLettre.s=Mid(strReturn,Position+1)
TableDecim.s(12)=EnLettre ; Memo Pour Debug
ProcedureReturn EnLettre
EndProcedure
;' -------------------------------------------------------------------------------------------------------------------------------
; Decodage et moteur de Conversion a proprement parlé
;---------------------------------------------------------------------------------------------------------------------------
Procedure.s Decodage(nb.s)
Protected nb1.s
Shared Decode$
Repeat ;suppression des zéros à droite de la partie décimale
If Right(nb, 1) = "0"
nb = Left(nb, Len(nb) - 1)
EndIf
Until Right(nb, 1)<>"0"
;
Select Len(nb)
Case 0
Decode$ = ""
Case 1
Section.s="Chiffres"
Decode$ = LitDansFichierLettres(Section.s, nb.s)
Case 2
If Val(nb) < 17
Section.s="Chiffres"
Decode$ = LitDansFichierLettres(Section.s, nb.s)
Else
nb1=Str(Int(Val(nb)/10)*10) ; prend la partie dizaine
Section.s="Chiffres"
Decode$ = LitDansFichierLettres(Section.s, nb1)
nb1 = Right(nb, 1)
Decode$=Decode$+"-"+LitDansFichierLettres(Section.s, nb1)
EndIf
If Right(Decode$, 2)="un" And nb > "20" : Decode$=Left(Decode$, Len(Decode$) - 2)+"et un":EndIf
If Right(Decode$, 4)="zéro" : Decode$=Left(Decode$, Len(Decode$) - 5):EndIf
Case 3 ; <<< A Partir d'ici on entre dans le domaine de la récursivité >>>
If Left(nb, 1)="1" ;---------------------------------------------------------------------------------------
Decode$ = "cent "+Decodage(Mid(nb, 2))
Else
Decode$ = Decodage(Left(nb, 1))+" cent "+Decodage(Mid(nb, 2))
If Right(Decode$, 6) = " cent " : Decode$ = Left(Decode$, Len(Decode$) - 1)+"s":EndIf
EndIf
Case 4 To 6
Decode$ =Decodage(Left(nb, Len(nb) - 3))+" mille "+Decodage(Right(nb, 3))
If Left(Decode$, 2) = "un" : Decode$ = Mid(Decode$, 4):EndIf
Case 7 To 9
Decode$ = Decodage(Left(nb, Len(nb) - 6))+" millions "+Decodage(Right(nb, 6))
If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 10)+Mid(Decode$, 12):EndIf
Case 10 To 12
Decode$ = Decodage(Left(nb, Len(nb) - 9))+" milliards "+Decodage(Right(nb, 9))
If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 11)+Mid(Decode$, 13):EndIf
EndSelect
ProcedureReturn Decode$
EndProcedure
;---------------------------------------------------------------------------------------------------------------------------
; Conversion de Nb ...
;---------------------------------------------------------------------------------------------------------------------------
Procedure.s Conversion(nb.s)
Protected NbDeci.s ; Préserve quelques données
Protected Affichage.s ; a usage locale...
Protected Entier.s
Protected Decimal.s
Pos.w=FindString(nb, ",",1) ; Au cas ou "nb" c'est un...
If Pos.w = 0 ; un entier
Affichage =Decodage(nb)+" unité "; OU
Else ; un décimal ce qui change tout ...
Repeat ; suppression des zéros à droite de la partie décimale
If Right(nb, 1) = "0" : nb = Left(nb, Len(nb) - 1):EndIf
Until Right(nb, 1)<>"0"
Entier=Left(nb, FindString(nb, ",",1) - 1) ; Prise de la partie entière
Decimal=Mid(nb, FindString(nb, ",",1) + 1) ; Prise de la partie décimale
; <<<<< Décodage de la partie entière >>>>>>> ------------------------------------------------
Entier = Decodage(Entier) ; Decodage de la partie entière de nb
If Right(Entier, 2) = "un" : Entier = Entier+"e":EndIf
If Entier = "une" :Entier = Entier+" unité ": Else :If Entier <> "" : Entier = Entier+" unités ":EndIf: EndIf
; <<<<< Décodage de la partie Decimale >>>>>>> ---------------------------------------------
NbDeci=Str(Len(Decimal))
Decimal = Decodage(Decimal) ; Et enfin, expression du type d'unitée...
Affichage = Entier+Decimal+" "
Affichage = Affichage +LitDansFichierLettres("Decimale", NbDeci)
If Decimal<>"un" : Affichage = Affichage +"s":EndIf
EndIf
ProcedureReturn Affichage
EndProcedure
;------------------------------------------------------------------------------------------------------
; Initialisation des tables de la représentation littérale
; START PROGRAMME
;------------------------------------------------------------------------------------------------------
Repeat ; Partie de lecture des DATA qui pourrait -être lus sur disque et donc modifiables
Read Numero$ ; sans entrer dans le programme pour un executable par exemple ....
If Numero$<>"FinDecimale" ; Mais la forme sur disque devrait respecter strictement l'ordre ci dessous et
Num=Val(Numero$) ; se terminer absolument par "FinEntier" et "FinDecimale"
If Entier=0 ; A noter que le mot "unité" peut être rempalcer par ce que l'on veut...
If Numero$="FinEntier" ; Exemple : euros ou mètres pour plus d'un...
Entier=1
Else
TableEntier(Num)=Numero$:
EndIf
Else
TableDecim(Num)=Numero$
EndIf
EndIf
Until Numero$="FinDecimale" ; recherche "FinDecimale" qui marque la fin du fichier
;
DataSection
MesChiffres:
Data.s "0=zéro","1=un","2=deux","3=trois","4=quatre","5=cinq","6=six","7=sept","8=huit","9=neuf","10=dix","11=onze"
Data.s "12=douze","13=treize","14=quatorze","15=quinze","16=seize"
Data.s "20=vingt","30=trente","40=quarante","50=cinquante","60=soixante","70=septante","80=quatre-vingt","90=nonante","FinEntier"
;[Decimale]
Data.s "1=dixième","2=centième","3=millième","4=dix-millième","5=cent-millième","6=millionième","7=dix-millionième"
Data.s "8=cent-millionième","9=milliardième","10=dix-milliardième","11=cent-milliardième","FinDecimale"
EndDataSection
; ****************************************************************************************************************
; Début de programme pour l'utilisateur et prise de la valeur à convertir
; ****************************************************************************************************************
NbrBase.s="1234,567"
Repeat
; Entré de la valeur à convertir
Nombre= InputRequester("Transformeur","Donnez votre valeur : ",NbrBase)
ReplaceString(Nombre, ".",",",2) ; Vérifie que les points, s'il y a, deviennent virgules...
NbrBase=Nombre
Reponse$=Conversion(Nombre) ; APPEL ICI et REPONSE ICI
; ; PUIS <<< Affichage de la conversion !!!! >>>
Resultat=MessageRequester("Pour : "+Nombre+" Autre cas ? ",Reponse$,#PB_MessageRequester_YesNo)
Until Resultat = 7
;
End
;*******************************************************************************************************************
Code : Tout sélectionner
Procedure.s Decodage(nb.s)
Protected nb1.s
Shared Decode$
; ET CECI N'AVAIS RIEN A FAIRE ICI PUISQUE POUR DECIMALE
; et cela transformais 200 en 2 et 12200 en 122 etc...
; normal les zéros à droite des décimales c'est comme ceux à gauche des entiers
;
;Repeat ; suppression des zéros à droite de la partie décimale
; If Right(nb, 1) = "0"
; nb = Left(nb, Len(nb) - 1) <<< Cruel oubli de recopie d'une partie dans l'autre >>>
; EndIf
; Until Right(nb, 1)<>"0"
;
Select Len(nb)
Case 0
Decode$ = ""
Case 1
Section.s="Chiffres"
Decode$ = LitDansFichierLettres(Section.s, nb.s)
Case 2
If Val(nb) < 17
Section.s="Chiffres"
Decode$ = LitDansFichierLettres(Section.s, nb.s)
Else
nb1=Str(Int(Val(nb)/10)*10) ; prend la partie dizaine
Section.s="Chiffres"
Decode$ = LitDansFichierLettres(Section.s, nb1)
nb1 = Right(nb, 1)
Decode$=Decode$+"-"+LitDansFichierLettres(Section.s, nb1)
EndIf
If Right(Decode$, 2)="un" And nb > "20" : Decode$=Left(Decode$, Len(Decode$) - 2)+"et un":EndIf
; >> CI-DESSOUS >> Ajoutée car pour terminaisons par vingt cela doit être "et une" et non "et un"<
If Right(Decode$, 2)="un" And nb = "20" : Decode$=Left(Decode$, Len(Decode$) - 2)+"et une":EndIf
If Right(Decode$, 4)="zéro" :Decode$=Left(Decode$, Len(Decode$) - 5):EndIf
Case 3 ; <<< A Partir d'ici on entre dans le domaine de la récursivité >>>
;If Left(nb, 1)="1" <<<<=== CECI EST A REMPLACER PAR CI DESSOUS
; Car cela donnait pour 12021 => douze mille zéro cent ving-et-un
If Left(nb, 1)="1" Or Left(nb, 1)="0" ;------------------------------
Decode$ = "cent "+Decodage(Mid(nb, 2))
Else
Decode$ = Decodage(Left(nb, 1))+" cent "+Decodage(Mid(nb, 2))
If Right(Decode$, 6) = " cent " : Decode$ = Left(Decode$, Len(Decode$) - 1)+"s":EndIf
EndIf
Case 4 To 6
Decode$ =Decodage(Left(nb, Len(nb) - 3))+" mille "+Decodage(Right(nb, 3))
If Left(Decode$, 2) = "un" : Decode$ = Mid(Decode$, 4):EndIf
Case 7 To 9
Decode$ = Decodage(Left(nb, Len(nb) - 6))+" millions "+Decodage(Right(nb, 6))
If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 10)+Mid(Decode$, 12):EndIf
Case 10 To 12
Decode$ = Decodage(Left(nb, Len(nb) - 9))+" milliards "+Decodage(Right(nb, 9))
If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 11)+Mid(Decode$, 13):EndIf
EndSelect
ProcedureReturn Decode$
EndProcedure
En plus il faudrait y ajouter des "Euros" si on parle d'argent, de "telle ou telle autre" expression de mesure que ce soit des quantités, des vitesses, volumes etc... Auxquels cas nous aurions "mille deux cent mètres et 25 centimètres", ou "mille deux cent euros et vingt cinq cents"