1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| #include <stdio.h>
#include <string.h>
/* cette fonction va permettre de savoir dans quelle case du tableau unites
il faut aller chercher la valeur, pour connaitre l'unité à afficher
par exemple, le nombre 304 fait 3 caractères, donc correspond au cas !(len%3),
donc on va piocher la valeur de la case d'indice 1, c'est à dire "cent"
*/
int return_unit(int len){
if (len==10 || len == 11)
return 4 ;
if (len==8 || len==7)
return 3 ;
if (len==5 || len==4)
return 2 ;
if (!(len%3))
return 1;
return 0;
}
int main (void)
{char nb[15];
char nbstr[256] = "";
int len, tmplen ;
char unites [][10] ={"", "cent ", "mille ", "million ", "milliard "};
char dizaines [][14] = {"", "dix ", "vingt ", "trente ", "quarante ", "cinquante ", "soixante ", "soixante", "quatre-vingt ", "quatre-vingt"} ;
char nombres [][11] = {"", "et un ", "deux ", "trois ", "quatre ", "cinq ", "six ", "sept ", "huit ", "neuf ", "dix ", "onze ", "douze ", "treize ", "quatorze ", "quinze ", "seize ", "dix-sept ", "dix-huit ", "dix-neuf "};
/* la conversion peut se faire jusqu'aux centaines de milliard */
printf("entrer un nombre (0<=nb<=999 999 999 999) : ");
scanf("%s", nb);
/* attention : nb est bien une chaine de caractères qui contient les caractères représentant le nombre entré */
tmplen = len = strlen(nb) ; /* nombre de caractères du nombre entré */
if (len==1 && nb[0]==48) /* on commence à 48 qui correspond à 0 (zéro) dans la table ascii */
strcat(nbstr, "z\x82ro") ;
else{
/* bon c'est là que les choses sérieuses commencent ;-)
on va réduire petit à petit jusqu'à 0 le nombre de caractères qui constituent le nombre entré
le traitement va être fait par groupe de 3 caractères :
3 car à chaque fois c'est la même chose : 1 (un) --> 10 (dix) --> 100 (cent),
puis quand on passe à mille c'est pareil : 1 000 (un mille) --> 10 000 (dix mille) --> 100 000 (cent mille)
etc...
*/
while (tmplen>0){
switch (tmplen % 3) { /* on teste la valeur de cette expression : 0, 1 ou 2 ; % == modulo == reste de la division euclidienne */
case 0 : /* tmplen est un multiple de 3 (par exemple 123 000) */
if ((nb[len-tmplen]-48) != 1)
/* vrai si le 1er caractère du groupe de 3 n'est pas 1
par exemple 213 456:
lors du 1er passage ici tmplen==6 et len==6 -> 1er caractère du groupe de 3 est 2
lors du 2ème passage ici tmplen==3 et len==6 -> 1er caractère du groupe de 3 est 4
*/
strcat(nbstr, nombres[nb[len-tmplen]-48]);
if (!(nb[len-tmplen]-48))
/* si le 1er caractère est 0, comme lors du 2ème passage pour le nombre 123 000, on sort du switch */
break;
/* pour finir on ajoute le mot cent à la suite */
strcat(nbstr, unites[return_unit(tmplen)]) ;
break;
case 2 : /* tmplen vaut 2, 5, 8 ou 11
par exemple nb==21534 --> 2 lors du 1er passage dans la boucle ou 3 lors du 2ème passage ici
ou nb==123456 --> 2 lors du 2ème passage dans boucle, etc...*/
if (!(nb[len-tmplen]-48))
/* si car ==0 comme le 0 dans 102, on sort du switch */
break;
if ((nb[len-tmplen]-48) == 1) {
/* si le caractère est 1, comme dans 17 ou 18999
on voit donc que c'est dix-quelquechose
on décéremente tmplen et on regarde donc ce qui suit le 1
on va chercher la correspondance dans le tableau nombres */
strcat(nbstr, nombres[10+(nb[len-(--tmplen)]-48)]) ;
/* puis on ajoute l'unité (mille dans le 2ème exemple) */
strcat(nbstr, unites[return_unit(tmplen)]) ;
break ;
}
/* si on est ici, c'est donc que le caractère n'est ni 0 ni 1
donc c'est le début d'un multiple de 10 (20, 30, 40...) */
strcat(nbstr, dizaines[nb[len-tmplen]-48]);
/* cas particulier de 7 et 9 qui en dizaine donnent par exemple
soixante et onze (71) au lieu de septente et un (71) comme pour nos amis belges ;-) */
if ((nb[len-tmplen]-48) == 7 || (nb[len-tmplen]-48) == 9) {
if (!(nb[len-(tmplen-1)]-48))
/* cas où c'est 70 ou 90 */
strcat(nbstr, "-dix ");
else {
if (nb[len-(tmplen-1)]-48 == 1)
/* cas 71 ou 91 */
strcat(nbstr, " et ");
else
/* les autres cas 7x et 9x */
strcat(nbstr, "-");
/* comme plus haut, on ajoute le nombre puis l'unité du groupe de 3 */
strcat(nbstr, nombres[10+(nb[len-(--tmplen)]-48)]) ;
strcat(nbstr, unites[return_unit(tmplen)]) ;
}
}
break;
case 1 : /* tmplen vaut 1, 4, 7, 10 */
if ((nb[len-tmplen]-48)==1) {
if (len==tmplen || !(nb[len-tmplen-1]-48)){
/* nb==1 ou nb==1 xxx ou nb==1 xxx xxx ou nb == 1 xxx xxx xxx
ou nb==(xxx){0,3) x01 (xxx){0,3)
cas particulier : 1xxx */
if (len != 4)
strcat(nbstr, "un ") ;
}
else /* par exemple le 1 de 21 */
strcat(nbstr, nombres[1]);
}
else /* un autre chiffre que 1 */
strcat(nbstr, nombres[nb[len-tmplen]-48]);
strcat(nbstr, unites[return_unit(tmplen)]) ;
break ;
}
tmplen-- ; /* on décémente tmplen avant la prochaine itération */
}
}
printf("\n--> %s\t-->%s\n", nb, nbstr);
system("pause");
return 0;
} |
Partager