Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercices pour débutants en C

Au menu : zSommeChiffres (nombres, algo)

6 janvier 2010 à 7:46:24

Citation : GurneyH


@candide : Pour le code de Bad_Wolf, c'est l'erreur signalée par Pouet, (pointeur p incrémenté, et free() sur ce pointeur, invalide à la fin de la fonction.).




Comme Bad_Wolf a dit

Citation : Bad_Wolf

Ouh, bien vu pour le free(p); . ;)
Le souci c'est que je modifie la chaîne en cours de route, et que je trouve ça plus propre de laisser la chaîne passée en entrée intacte



je n'avais pas de raison de penser que son erreur était si grave. Il faut que Bad_Wolf sache qu'on peut rééditer son message pour corriger d'éventuelles erreurs ...
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 12:04:48

Citation : candide

On n'écrit pas dixaine mais dizaine.


Bien vu ^^
C'est parce qu'au départ j'avais appelé mon tableau 'dix' et que je l'ai renommé parce que j'ai appelé ma fonction 'dix' :lol:

Pour la taille des tableaux c'est un point de repère, comme ça en voyant la taille des tableaux je sais ce que je gère ;)

C'est vrai que le "cent" n'a rien à faire dans le tableau je te l'accorde ^^
Pour la répétition de soixante et quatre-vingt c'est pour éviter de me faire ch*** après avec des indices différents. J'ai mis exactement le nombre de cases pour accéder directement à la bonne case du tableau. Ca peut se discuter mais je pense que c'est plus simple pour y accéder ensuite dans le code :)


Citation : GurneyH

@Pouet: Effectivement, ton code est très compliqué...
A un moment donné, je pense que c'est important d'écrire du code qui soit lisible et compréhensible par d'autres(même moins avancés.)
Par exemple :

for (i = len-1-(3*j); i >= 0 && i >= len-3*(j+1); i--, mult*=10)


C'est une perle. :p

Sinon à l'usage, je n'ai pas trouvé d'erreurs. :) .


Ah ? :euh:
Même en me relisant je ne trouve pas que ce soit si compliqué que ça :euh:
Bon après c'est mon point de vue ^^
Je vais reposter le code avec des commentaires (et sûrement quelques modifs).

Bah quoi elle te plait pas ma boucle ? :lol:

Bon si ya pas d'erreurs ça me rassure :p

Edit : Commentaires à mort ! xD
J'ai modifié 2 ou 3 trucs aussi :)
Edit2 : Encore une toute petit modif.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ============ Variables globales ============ */
#pragma mark -
#pragma mark globales

char const * const unites [20] = {
	"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
	"dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"
};

char const * const dizaines [10] = {
	"", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante",
	"quatre-vingt", "quatre-vingt"
};

char const * const centaines [] = {
	"mille", "million", "millard"
};

/* ============ Fonctions ============ */
#pragma mark -

/* Fonction qui prend en argument 1 nombre entre 0 et 99 (tous 2 inclus).
 * Une chaîne de caractère 'str' dans laquelle on va mettre la décomposition du nombre.
 * Un paramètre 'esse' pour savoir si c'est le dernier nombre.
 * Si c'est le dernier nombre et que c'est 80 on met un esse.
 * Un paramètre 'mil' pour savoir si le nombre est 1000 (mille).
 */

void dix(int nb, char *str, int esse, int mil) {
	char tmp[100] = "";
	/* On décompose notre nombre. */
	int unit = nb % 10;
	int disse = nb / 10;
	
	/* Si le nombre est 0 on ne renvoie pas "zero" parce que
	 * le nombre 0 est géré tout au début.
	 */
	if (nb == 0)
		return;
	
	/* Si le nombre est 1000 on ne fait rien.
	 * On ne dit pas 'un mille' mais 'mille' tout court. */
	if (nb == 1 && mil == 1)
		return;
	
	/* Si le nombre est inférieur à 20 on va piocher directement
	 * dans le tableau des unites. */
	if (nb < 20) {
		strcat(str, unites[nb]);
		strcat(str, " ");
		return;
	}
	
	/* Si le nombre est 80 on renvoie ce nombre.
	 * Si on la variable 'esse' (parce que c'est le dernier nombre)
	 * on rajoute le 's'.
	 */
	if (nb == 80) {
		strcat(str, dizaines[disse]);
		if (esse)
			strcat(str, "s");
		strcat(str, " ");
		return;
	}
	
	/* On copie les dizaines dans notre variable temporaire. */
	strcat(tmp, dizaines[disse]);
	
	/* Si notre nombre se fini par 1 mais n'est pas 80 ou 90
	 * on mets " et " sinon un trait d'union '-'.
	 */
	if (unit == 1 && disse != 8 && disse != 9)
		strcat(tmp, " et ");
	else
		strcat(tmp, "-");
	
	/* Si notre nombre est dans les 70 ou 90 on écris les unites
	 * supérieurs à 10. On dit soixante et onze, quatre-vingt-treize etc.
	 * Sinon on mets tout simpleme les unites de 1 à 9.
	 */
	if (disse == 7 || disse == 9)
		strcat(tmp, unites[unit+10]);
	else if (unit != 0)
		strcat(tmp, unites[unit]);
	
	/* On mets notre variable temporaire dans la variable passee
	 * en parametre et on rajoute un espace à la fin.
	 */
	strcat(str, tmp);
	strcat(str, " ");
}

/* Fonction qui décompose la centaine du nombre.
 * La fonction prend un nombre sur 3 chiffres 0 <= nb <= 999.
 * Les autres sont les mêmes paramètres que la fonction dix.
 */

void cent(int nb, char *str, int esse, int mil) {
	char tmp[100] = "";
	
	if (nb > 99) {
		/* On récupère le nombre de la centaine. */
		int mod = nb / 100;
		
		/* Si notre nombre est supérieur à 1 on mets les unités.
		 * On ne dit pas 'un cent'.
		 */
		if (mod > 1)
			sprintf(tmp, "%s ", unites[mod]);
		strcat(tmp, "cent");
		
		/* Si on à esse et que notre nombre est une centaine 'entière'
		 * supérieur à 100 on met un 's'.
		 */
		if (esse && mod > 1 && nb % 100 == 0)
			strcat(tmp, "s");
		strcat(tmp, " ");
	}
	/* On envoie les 2 chiffres du nombre à la fonction 'dix'.
	 * Notre variable temporaire et les 2 paramètres.
	 */
	dix(nb % 100, tmp, esse, mil);
	
	/* On concatène notre variable temporaire dans notre chaîne
	 * passée en argument.
	 */
	strcpy(str, tmp);
}

/* Fonction qui prend une chaîne qui contient le nombre à décomposer.
 * Retourne le nombre en toutes lettres.
 */

char * z0zero(char const *src) {
	/* Variable qui contiendra le resultat. */
	static char res[500];
	/* Variable temporaire. */
	char str[500] = "";
	int i, j;
	int len = strlen(src);
	int tmp, mult, esse = 1;
	int mil = 0;
	
	/* Bon là je me suis pas fait chier 
	 * Si le nombre est 0 on renvoie "zero".
	 */
	if (strtol(src, NULL, 10) == 0) {
		sprintf(res, "%s", unites[0]);
		return res;
	}
	
	/* On parcoures notre tableau 'centaine'.
	 * 0 == "cent", 1 == "mille", 2 == "million", 3 == "milliard"
	 */
	for (j = 0; j < 4; j++) {
		/* On initialises nos variables */
		tmp = 0;
		mult = 1;
		/* On 'vide' notre chaîne. */
		*str = '\0';
		/* Si le nombre est mille ou pas.
		 * "mille" est invariable, c'est pour le 's'. */
		if (j == 1)
			mil = 1;
		else
			mil = 0;
		
		/* Bon là c'est du charabiat 
		 * Je parcoures ma chaîne depuis la fin jusqu'au début tous les 3caractères.
		 * Je gère ça en fonction de 'j'. Je vais voir pour p-e l'améliorer.
		 * Cette boucle sert à convertir la chaîne en nombre.
		 */
		for (i = len-1-(3*j); i >= 0 && i >= len-3*(j+1); i--, mult*=10)
			tmp += (src[i] - '0') * mult;
		
		/* On décompose notre nombre */
		cent(tmp, str, esse, mil);
		
		/* Si j == 0 on est < 999 donc on ne fait rien.
		 * Si tmp == 0 le nombre ne peut pas être "zero" -> On saute.
		 */
		if (j != 0 && tmp != 0) {
			/* On concatènes mille, million ou millard. */
			strcat(str, centaines[j-1]);
			/* Si notre nombre est != 1 on ne met pas de 's'
			 * Si 'j' != 1 on ne met pas de 's' non plus (on ne dit pas un mille).
			 */
			if (tmp != 1 && j != 1)
				strcat(str, "s ");
			else
				strcat(str, " ");
		}
		/* On concatène le resultat à notre chaîne.
		 * Si on avait 'trois cents' dans res et 'mille' dans str on a :
		 * 'mille trois cents'
		 */
		strcat(str, res);
		/* On mets le resultat dans res maintenant  */
		strcpy(res, str);
		/* Les 2 lignes du dessus sont importantes, c'est elles qui font la magie  */
		
		/* Si i < 0 bah on est arrivé à la fin de la chaîne donc on quitte. */
		if (i < 0)
			break;
		/* On met esse à 0. Le 's' n'est valable que pour la fin. */
		esse = 0;
	}
	
	return res;
}

/* 999 999 999 999 */

int main(void) {
	char * str = "999999999999";
	
	printf("%s", z0zero(str));
	return EXIT_SUCCESS;
}

  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 14:33:40

Citation : Pouet_forever


Regarde mon code juste au dessus du tiens.



Pas une bonne méthode à mon avis de mettre sa solution dans un EDIT, moi je ne l'avais même pas vue.


Citation : Pouet_forever


Edit : Voilà en code "normal" :



C'est vrai que ton code est relativement court.

Je ne trouve pas que l'algorithme apparaisse clairement.

Dans l'ensemble, les sorties sont correctes.

Il y a néanmoins quelques erreurs (liste non exhaustive) :

630
six cent trente-


60000000      
soixante- millions


400000000
quatre cent millions


(quatre cents millions plutôt me semble-t-il)

80000000
quatre-vingt millions


(quatre-vingts millions plutôt me semble-t-il).

Noter que la référence donnée par GurneyH est assez floue sur certains de ces points. Finalement, il apparait qu'il aurait été plus simple de demander d'écrire plutôt en anglais des nombres en lettres.








  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 16:32:28

Citation : candide

Pas une bonne méthode à mon avis de mettre sa solution dans un EDIT, moi je ne l'avais même pas vue.


Bah ... j'ai pas le choix je ne peux pas poster 2 messages de suite en 24h ^^

Pour les 2 derniers points j'étais pas sûr mais je viens de vérifier et c'est bien ça. Ca me fait une variable en moins :-°
Pour le reste il manquait juste un if :)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ============ Variables globales ============ */
#pragma mark -
#pragma mark globales

char const * const unites [20] = {
	"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
	"dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"
};

char const * const dizaines [10] = {
	"", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante",
	"quatre-vingt", "quatre-vingt"
};

char const * const centaines [] = {
	"mille", "million", "millard"
};

/* ============ Fonctions ============ */
#pragma mark -

/* Fonction qui prend en argument 1 nombre entre 0 et 99 (tous 2 inclus).
 * Une chaîne de caractère 'str' dans laquelle on va mettre la décomposition du nombre.
 * Un paramètre 'mil' pour savoir si le nombre est 1000 (mille).
 */

void dix(int nb, char *str, int mil) {
	char tmp[100] = "";
	/* On décompose notre nombre. */
	int unit = nb % 10;
	int disse = nb / 10;
	
	/* Si le nombre est 0 on ne renvoie pas "zero" parce que
	 * le nombre 0 est géré tout au début.
	 */
	if (nb == 0)
		return;
	
	/* Si le nombre est 1000 on ne fait rien.
	 * On ne dit pas 'un mille' mais 'mille' tout court. */
	if (nb == 1 && mil == 1)
		return;
	
	/* Si le nombre est inférieur à 20 on va piocher directement
	 * dans le tableau des unites. */
	if (nb < 20) {
		strcat(str, unites[nb]);
		strcat(str, " ");
		return;
	}
	
	/* Si le nombre est 80 on renvoie ce nombre. */
	if (nb == 80) {
		strcat(str, dizaines[disse]);
		strcat(str, "s ");
		return;
	}
	
	/* On copie les dizaines dans notre variable temporaire. */
	strcat(tmp, dizaines[disse]);
	
	/* Si notre nombre se fini par 1 mais n'est pas 80 ou 90
	 * on mets " et " sinon un trait d'union '-'.
	 */
	if (unit == 1 && disse != 8 && disse != 9)
		strcat(tmp, " et ");
	else if (unit != 0)
		strcat(tmp, "-");
	else
		strcat(tmp, " ");
	
	/* Si notre nombre est dans les 70 ou 90 on écris les unites
	 * supérieurs à 10. On dit soixante et onze, quatre-vingt-treize etc.
	 * Sinon on mets tout simpleme les unites de 1 à 9.
	 */
	if (disse == 7 || disse == 9)
		strcat(tmp, unites[unit+10]);
	else if (unit != 0)
		strcat(tmp, unites[unit]);
	
	/* On mets notre variable temporaire dans la variable passee
	 * en parametre et on rajoute un espace à la fin.
	 */
	strcat(str, tmp);
	strcat(str, " ");
}

/* Fonction qui décompose la centaine du nombre.
 * La fonction prend un nombre sur 3 chiffres 0 <= nb <= 999.
 * Les autres sont les mêmes paramètres que la fonction dix.
 */

void cent(int nb, char *str, int mil) {
	char tmp[100] = "";
	
	if (nb > 99) {
		/* On récupère le nombre de la centaine. */
		int mod = nb / 100;
		
		/* Si notre nombre est supérieur à 1 on mets les unités.
		 * On ne dit pas 'un cent'.
		 */
		if (mod > 1)
			sprintf(tmp, "%s ", unites[mod]);
		strcat(tmp, "cent");
		
		/* Si notre nombre est une centaine 'entière'
		 * supérieure à 100 on met un 's'.
		 */
		if (mod > 1 && nb % 100 == 0)
			strcat(tmp, "s");
		strcat(tmp, " ");
	}
	/* On envoie les 2 chiffres du nombre à la fonction 'dix'.
	 * Notre variable temporaire et les 2 paramètres.
	 */
	dix(nb % 100, tmp, mil);
	
	/* On concatène notre variable temporaire dans notre chaîne
	 * passée en argument.
	 */
	strcpy(str, tmp);
}

/* Fonction qui prend une chaîne qui contient le nombre à décomposer.
 * Retourne le nombre en toutes lettres.
 */

char * z0zero(char const *src) {
	/* Variable qui contiendra le resultat. */
	static char res[500];
	/* Variable temporaire. */
	char str[500] = "";
	int i, j;
	int len = strlen(src);
	int tmp, mult;
	int mil = 0;
	
	/* Bon là je me suis pas fait chier 
	 * Si le nombre est 0 on renvoie "zero".
	 */
	if (strtol(src, NULL, 10) == 0) {
		sprintf(res, "%s", unites[0]);
		return res;
	}
	
	/* On parcoures notre tableau 'centaine'.
	 * 0 == "cent", 1 == "mille", 2 == "million", 3 == "milliard"
	 */
	for (j = 0; j < 4; j++) {
		/* On initialises nos variables */
		tmp = 0;
		mult = 1;
		/* On 'vide' notre chaîne. */
		*str = '\0';
		/* Si le nombre est mille ou pas.
		 * "mille" est invariable, c'est pour le 's'. */
		if (j == 1)
			mil = 1;
		else
			mil = 0;
		
		/* Bon là c'est du charabiat 
		 * Je parcoures ma chaîne depuis la fin jusqu'au début tous les 3 caractères.
		 * Je gère ça en fonction de 'j'. Je vais voir pour p-e l'améliorer.
		 * Cette boucle sert à convertir la chaîne en nombre de 3 chiffres.
		 */
		for (i = len-1-(3*j); i >= 0 && i >= len-3*(j+1); i--, mult*=10)
			tmp += (src[i] - '0') * mult;
		
		/* On décompose notre nombre */
		cent(tmp, str, mil);
		
		/* Si j == 0 on est < 999 donc on ne fait rien.
		 * Si tmp == 0 le nombre ne peut pas être "zero" -> On saute.
		 */
		if (j != 0 && tmp != 0) {
			/* On concatènes mille, million ou millard. */
			strcat(str, centaines[j-1]);
			/* Si notre nombre est != 1 on ne met pas de 's'
			 * Si 'j' != 1 on ne met pas de 's' non plus (on ne dit pas un mille).
			 */
			if (tmp != 1 && j != 1)
				strcat(str, "s ");
			else
				strcat(str, " ");
		}
		/* On concatène le resultat à notre chaîne.
		 * Si on avait 'trois cents' dans res et 'mille' dans str on a :
		 * 'mille trois cents'
		 */
		strcat(str, res);
		/* On mets le resultat dans res maintenant  */
		strcpy(res, str);
		/* Les 2 lignes du dessus sont importantes, c'est elles qui font la magie  */
		
		/* Si i < 0 bah on est arrivé à la fin de la chaîne donc on quitte. */
		if (i < 0)
			break;
	}
	
	return res;
}

/* 999 999 999 999 */

int main(void) {
	char * str = "600000";
	
	printf("%s -> ", str);
	printf("%s", z0zero(str));
	return EXIT_SUCCESS;
}

J'ai trouvé 2 autres liens si ça intéresse du monde :
Les nombres sur Wikipédia
Un autre site ^^
J'avais aussi trouvé une table de nombre sur le site du conjugueur mais j'arrive pas à remettre la main dessus :euh:
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 16:38:42

J'étais passés à travers ces erreur. J'ai fait un dizaine de tests mais pas les bons apparemment... :-°

Sinon, merci pour les liens Pouet, je les rajoute à l'énoncé... Merci
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
6 janvier 2010 à 16:58:56

Citation : Pouet_forever



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ============ Variables globales ============ */
#pragma mark -
#pragma mark globales

char const * const unites [20] = {
	"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
	"dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"
};

char const * const dizaines [10] = {
	"", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante",
	"quatre-vingt", "quatre-vingt"
};

char const * const centaines [] = {
	"mille", "million", "millard"
};

/* ============ Fonctions ============ */
#pragma mark -

/* Fonction qui prend en argument 1 nombre entre 0 et 99 (tous 2 inclus).
 * Une chaîne de caractère 'str' dans laquelle on va mettre la décomposition du nombre.
 * Un paramètre 'mil' pour savoir si le nombre est 1000 (mille).
 */

void dix(int nb, char *str, int mil) {
	char tmp[100] = "";
	/* On décompose notre nombre. */
	int unit = nb % 10;
	int disse = nb / 10;
	
	/* Si le nombre est 0 on ne renvoie pas "zero" parce que
	 * le nombre 0 est géré tout au début.
	 */
	if (nb == 0)
		return;
	
	/* Si le nombre est 1000 on ne fait rien.
	 * On ne dit pas 'un mille' mais 'mille' tout court. */
	if (nb == 1 && mil == 1)
		return;
	
	/* Si le nombre est inférieur à 20 on va piocher directement
	 * dans le tableau des unites. */
	if (nb < 20) {
		strcat(str, unites[nb]);
		strcat(str, " ");
		return;
	}
	
	/* Si le nombre est 80 on renvoie ce nombre. */
	if (nb == 80) {
		strcat(str, dizaines[disse]);
		strcat(str, "s ");
		return;
	}
	
	/* On copie les dizaines dans notre variable temporaire. */
	strcat(tmp, dizaines[disse]);
	
	/* Si notre nombre se fini par 1 mais n'est pas 80 ou 90
	 * on mets " et " sinon un trait d'union '-'.
	 */
	if (unit == 1 && disse != 8 && disse != 9)
		strcat(tmp, " et ");
	else if (unit != 0)
		strcat(tmp, "-");
	
	/* Si notre nombre est dans les 70 ou 90 on écris les unites
	 * supérieurs à 10. On dit soixante et onze, quatre-vingt-treize etc.
	 * Sinon on mets tout simpleme les unites de 1 à 9.
	 */
	if (disse == 7 || disse == 9)
		strcat(tmp, unites[unit+10]);
	else if (unit != 0)
		strcat(tmp, unites[unit]);
	
	/* On mets notre variable temporaire dans la variable passee
	 * en parametre et on rajoute un espace à la fin.
	 */
	strcat(str, tmp);
	strcat(str, " ");
}

/* Fonction qui décompose la centaine du nombre.
 * La fonction prend un nombre sur 3 chiffres 0 <= nb <= 999.
 * Les autres sont les mêmes paramètres que la fonction dix.
 */

void cent(int nb, char *str, int mil) {
	char tmp[100] = "";
	
	if (nb > 99) {
		/* On récupère le nombre de la centaine. */
		int mod = nb / 100;
		
		/* Si notre nombre est supérieur à 1 on mets les unités.
		 * On ne dit pas 'un cent'.
		 */
		if (mod > 1)
			sprintf(tmp, "%s ", unites[mod]);
		strcat(tmp, "cent");
		
		/* Si notre nombre est une centaine 'entière'
		 * supérieure à 100 on met un 's'.
		 */
		if (mod > 1 && nb % 100 == 0)
			strcat(tmp, "s");
		strcat(tmp, " ");
	}
	/* On envoie les 2 chiffres du nombre à la fonction 'dix'.
	 * Notre variable temporaire et les 2 paramètres.
	 */
	dix(nb % 100, tmp, mil);
	
	/* On concatène notre variable temporaire dans notre chaîne
	 * passée en argument.
	 */
	strcpy(str, tmp);
}

/* Fonction qui prend une chaîne qui contient le nombre à décomposer.
 * Retourne le nombre en toutes lettres.
 */

char * z0zero(char const *src) {
	/* Variable qui contiendra le resultat. */
	static char res[500];
	/* Variable temporaire. */
	char str[500] = "";
	int i, j;
	int len = strlen(src);
	int tmp, mult;
	int mil = 0;
	
	/* Bon là je me suis pas fait chier 
	 * Si le nombre est 0 on renvoie "zero".
	 */
	if (strtol(src, NULL, 10) == 0) {
		sprintf(res, "%s", unites[0]);
		return res;
	}
	
	/* On parcoures notre tableau 'centaine'.
	 * 0 == "cent", 1 == "mille", 2 == "million", 3 == "milliard"
	 */
	for (j = 0; j < 4; j++) {
		/* On initialises nos variables */
		tmp = 0;
		mult = 1;
		/* On 'vide' notre chaîne. */
		*str = '\0';
		/* Si le nombre est mille ou pas.
		 * "mille" est invariable, c'est pour le 's'. */
		if (j == 1)
			mil = 1;
		else
			mil = 0;
		
		/* Bon là c'est du charabiat 
		 * Je parcoures ma chaîne depuis la fin jusqu'au début tous les 3 caractères.
		 * Je gère ça en fonction de 'j'. Je vais voir pour p-e l'améliorer.
		 * Cette boucle sert à convertir la chaîne en nombre de 3 chiffres.
		 */
		for (i = len-1-(3*j); i >= 0 && i >= len-3*(j+1); i--, mult*=10)
			tmp += (src[i] - '0') * mult;
		
		/* On décompose notre nombre */
		cent(tmp, str, mil);
		
		/* Si j == 0 on est < 999 donc on ne fait rien.
		 * Si tmp == 0 le nombre ne peut pas être "zero" -> On saute.
		 */
		if (j != 0 && tmp != 0) {
			/* On concatènes mille, million ou millard. */
			strcat(str, centaines[j-1]);
			/* Si notre nombre est != 1 on ne met pas de 's'
			 * Si 'j' != 1 on ne met pas de 's' non plus (on ne dit pas un mille).
			 */
			if (tmp != 1 && j != 1)
				strcat(str, "s ");
			else
				strcat(str, " ");
		}
		/* On concatène le resultat à notre chaîne.
		 * Si on avait 'trois cents' dans res et 'mille' dans str on a :
		 * 'mille trois cents'
		 */
		strcat(str, res);
		/* On mets le resultat dans res maintenant  */
		strcpy(res, str);
		/* Les 2 lignes du dessus sont importantes, c'est elles qui font la magie  */
		
		/* Si i < 0 bah on est arrivé à la fin de la chaîne donc on quitte. */
		if (i < 0)
			break;
	}
	
	return res;
}

/* 999 999 999 999 */

int main(void) {
	char * str = "80000000";
	
	printf("%s", z0zero(str));
	return EXIT_SUCCESS;
}


Ton code est pas mal même si je pense qu'on doit pouvoir un peu simplifier. Il reste encore quelques erreurs comme 600000 ou 90000.


  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 17:40:56

Pour 90000 c'est modifié (bah oui j'ai rajouté une condition sur un else mais j'ai pas remis le else :-° )
Mais pour 600000 je ne vois pas d'erreurs :euh:

600000 -> six cents mille
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
6 janvier 2010 à 20:59:18

Six cent mille, pas de s
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 20:59:50

Citation : Pouet_forever

Pour 90000 c'est modifié (bah oui j'ai rajouté une condition sur un else mais j'ai pas remis le else :-° )
Mais pour 600000 je ne vois pas d'erreurs :euh:

600000 -> six cents mille


Cent et Vingt prennent un s seulement s'ils sont précédés de quelque chose et s'il n'y a rien après donc dans ton cas c'est faux effectivement.
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 21:08:20

Citation : Pouet_forever

Pour 90000 c'est modifié (bah oui j'ai rajouté une condition sur un else mais j'ai pas remis le else :-° )
Mais pour 600000 je ne vois pas d'erreurs :euh:

600000 -> six cents mille


Regarde l'exemple fourni dans le site le conjugueur : deux cent mille. La règle est confirmée sur Wikipédia. De même, il y a une erreur pour 80000.


Attention, tu as écrit millard au lieu de milliard.


Petit détail : tes chaînes sont inutilement suivies d'un espace.

Je critique ton code mais je trouve que tu as bien bossé.


Citation : Erosquare


Cent et Vingt prennent un s seulement s'ils sont précédés de quelque chose et s'il n'y a rien après donc dans ton cas c'est faux effectivement.



Pas exactement, cf. quatre-vingts millions ou encore deux cents milliards. Et il y a des cas où les règles données ne sont pas claires.
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 21:40:31

Je ne sais pas pourquoi je me sens mal à l'aise avec cet exercice >_<
Je ne peux avoir des idées claires pour pouvoir le résoudre, j'ai fait un code à la limite 99 (quelle honte :honte: ) mais je doute que je puisse poursuivre =s

#include <stdio.h>
#include <string.h>

const char* to16[] = {"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
                      "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize"};
const char* tens[] = {"", "dix", "vingt", "trente", "quarante", "cinquante", "soixante", "", "quatre-vingt"};

char *z0zero(char *src, char *dst)
{
    int add10 = 0;
    char c = 0;
    for ( ; *src ; src++)
    {
        if (!((int)(strlen(src)-2)%3))
        {
            if (*src == '1')
                add10 = 1;
            else if (*src == '7' || *src == '9')
            {
                sprintf(dst, "%s%s", dst, tens[*src-'0'-1]);
                add10 = 1;
            }
            else
                sprintf(dst, "%s%s", dst, tens[*src-'0']);
        }
        else
        {
            if (add10)
            {
                if (*src-'0' <= 6)
                    if (c == '7' && *src == '1')
                        sprintf(dst, "%s et %s", dst, to16[10+*src-'0']);
                    else
                        sprintf(dst, c == '1' ? "%s%s" : "%s-%s", dst, to16[10+*src-'0']);
                else
                    sprintf(dst, c == '1' ? "%sdix-%s" : "%s-dix-%s" , dst, to16[*src-'0']);
                add10 = 0;
            }
            else
                if (*src == '1' && c != 0 && c != '8')
                    sprintf(dst, "%s et 1", dst);
                else if (!(*src == '0' && c != 0))
                    sprintf(dst, c == 0 ? "%s%s" : "%s-%s", dst, to16[*src-'0']);
        }
        c = *src;
    }
    return dst;
}

int main(void)
{
    char *s = "0";
    char res[256] = "";

    printf("%s -> %s\n", s, z0zero(s, res));

    return 0;
}


(En même temps, si vous avez des commentaires sur mon code :-° )
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 22:06:40

Mouais ... lol sur le site que j'ai donné ils marquent bien six cents mille ... Ils se sont trompés alors :euh:
Bon bah GurneyH tu peux l'enlever des sites à donner lol

Bon ... après lecture et relecture je pense avoir saisi le truc :D

Cent et 80 s'accordent quand ils ne sont pas suivis.
Cependant ils s'accordent uniquement avec millions, millards (et millers mais on s'en fou ici ^^ ). Mais il faut que ce soit un nombre "rond".
Ex :
quatre-vingts millards
trois cents millions
cinq cents millards
quatre-vingt mille


Si c'est bien ça je pense que ce code doit être bon :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ============ Variables globales ============ */
#pragma mark -
#pragma mark globales

char const * const unites [20] = {
	"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
	"dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"
};

char const * const dizaines [10] = {
	"", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante",
	"quatre-vingt", "quatre-vingt"
};

char const * const centaines [] = {
	"mille", "million", "milliard"
};

/* ============ Fonctions ============ */
#pragma mark -

/* Fonction qui prend en argument 1 nombre entre 0 et 99 (tous 2 inclus).
 * Une chaîne de caractère 'str' dans laquelle on va mettre la décomposition du nombre.
 * Un paramètre 'mil' pour savoir si le nombre est 1000 (mille).
 */

void dix(int nb, char *str, int mil, int esse) {
	char tmp[100] = "";
	int unit = nb % 10;
	int disse = nb / 10;
	
	if (nb == 0)
		return;
	
	if (nb == 1 && mil == 1)
		return;
	
	if (nb < 20) {
		strcat(str, unites[nb]);
		strcat(str, " ");
		return;
	}
	
	if (nb == 80) {
		strcat(str, dizaines[disse]);
		if (mil || !esse)
			strcat(str, " ");
		else
			strcat(str, "s ");
		return;
	}
	
	strcat(tmp, dizaines[disse]);
	
	if (unit == 1 && disse != 8 && disse != 9)
		strcat(tmp, " et ");
	else if (unit != 0)
		strcat(tmp, "-");
	else
		strcat(tmp, " ");
	
	if (disse == 7 || disse == 9)
		strcat(tmp, unites[unit+10]);
	else if (unit != 0)
		strcat(tmp, unites[unit]);
	
	strcat(str, tmp);
	strcat(str, " ");
}

/* Fonction qui décompose la centaine du nombre.
 * La fonction prend un nombre sur 3 chiffres 0 <= nb <= 999.
 * Les autres sont les mêmes paramètres que la fonction dix.
 */

void cent(int nb, char *str, int mil, int esse) {
	char tmp[100] = "";
	
	if (nb > 99) {
		int mod = nb / 100;
		
		if (mod > 1)
			sprintf(tmp, "%s ", unites[mod]);
		strcat(tmp, "cent");
		
		if (esse && !mil && mod > 1 && nb % 100 == 0)
			strcat(tmp, "s");
		strcat(tmp, " ");
	}
	
	dix(nb % 100, tmp, mil, esse);
	
	strcpy(str, tmp);
}

/* Fonction qui prend une chaîne qui contient le nombre à décomposer.
 * Retourne le nombre en toutes lettres.
 */

char * z0zero(char const *src) {
	static char res[500];
	char str[500] = "";
	int i, j;
	int len = strlen(src);
	int tmp, mult;
	int mil = 0, esse = 1;
	
	if (strtol(src, NULL, 10) == 0) {
		sprintf(res, "%s", unites[0]);
		return res;
	}
	
	/* On parcoures notre tableau 'centaine'.
	 * 0 == "cent", 1 == "mille", 2 == "million", 3 == "milliard"
	 */
	for (j = 0; j < 4; j++) {
		tmp = 0;
		mult = 1;
		*str = '\0';
		/* Si le nombre est mille ou pas.
		 * "mille" est invariable, c'est pour le 's'. */
		if (j == 1)
			mil = 1;
		else
			mil = 0;
		
		for (i = len-1-(3*j); i >= 0 && i >= len-3*(j+1); i--, mult*=10)
			tmp += (src[i] - '0') * mult;
		
		cent(tmp, str, mil, esse);
		
		if (j != 0 && tmp != 0) {
			strcat(str, centaines[j-1]);
			if (tmp != 1 && j != 1)
				strcat(str, "s ");
			else
				strcat(str, " ");
		}
		
		strcat(str, res);
		strcpy(res, str);
		
		if (i < 0)
			break;
		if (tmp != 0)
			esse = 0;
	}
	
	return res;
}

/* 999 999 999 999 */

int main(void) {
	char * str = "80245100";
	
	printf("%s -> ", str);
	printf("%s", z0zero(str));
	return EXIT_SUCCESS;
}


C'est là qu'on voit que la langue anglaise est beaucoup plus simple ...

Merci pour le millard c'est corrigé :)
Pour les espaces je m'attendais à avoir la remarque ^^
Je les enlèverai quand le code sera 100% fonctionnel :D

Edit :
@ HighTam :

Même remarque qu'on m'a faite :p
Le 80 s'écrit : quatre-vingts

Fait attention à cette écriture j'ai déjà eu des problèmes. Mets des accolades :)

if (*src-'0' <= 6)
	if (c == '7' && *src == '1')
		sprintf(dst, "%s et %s", dst, to16[10+*src-'0']);
	else
		sprintf(dst, c == '1' ? "%s%s" : "%s-%s", dst, to16[10+*src-'0']);
else
	sprintf(dst, c == '1' ? "%sdix-%s" : "%s-dix-%s" , dst, to16[*src-'0']);


Citation : HighTam

(quelle honte :honte: )


Pourquoi ?
On est là pour s'entrainer non ? :)
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 22:46:56

Citation : Pouet_forever

Cent et 80 s'accordent quand ils ne sont pas suivis.
Cependant ils s'accordent uniquement avec millions, millards (et millers mais on s'en fou ici ^^ ). Mais il faut que ce soit un nombre "rond".
Ex :
quatre-vingts millards
trois cents millions
cinq cents millards
quatre-vingt mille





Rappel : pas millard mais milliard.

Concernant l'accord de vingt et de cent, l'Académie française donne une règle mais la formulation est assez peu précise :

:

Citation : Académie française

Vingt et cent se terminent par un s quand ils sont précédés d’un nombre qui les multiplie, mais ils restent invariables s’ils sont suivis d’un autre nombre ou de mille. On dira ainsi : deux cents euros mais deux cent vingt euros ; quatre-vingts hommes mais quatre-vingt-deux hommes.



Par conséquent, on ne sait pas vraiment comment on écrit le nombre 200.000.450 : deux cents millions quatre cent cinquante ou alors deux cent millions quatre cent cinquante ? Moi, je pencherais pour la première écriture (les tranches des 3 chiffres sont indépendantes) plutôt que la 2ème. J'ai consulté plusieurs livres de grammaire et aucun ne traite ce genre d'exemple, ils se contentent d'exemples de nombres ayant 2 ou 3 chiffres et aucun n'utilisent de millions ou de milliards.

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
6 janvier 2010 à 22:58:39

Personnellement, j'utiliserais la deuxième -> ici il est suivi d'un autre nombre, millions.
Je pense que l'Académie voulait exprimer que 200 000 serait deux cent mille (cent suivi de mille ici, million n'est que l'unité supérieure puis milliard etc.).
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 22:59:41

Citation : Pouet_forever

Même remarque qu'on m'a faite :p
Le 80 s'écrit : quatre-vingts


Bien vu ;) Merci !
Corrigé :) :

#include <stdio.h>
#include <string.h>

const char* to16[] = {"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
                      "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize"};
const char* tens[] = {"", "dix", "vingt", "trente", "quarante", "cinquante", "soixante", "", "quatre-vingt"};

char *z0zero(char *src, char *dst)
{
    int add10 = 0;
    char c = 0;
    for ( ; *src ; src++)
    {
        if (!((int)(strlen(src)-2)%3))
        {
            if (*src == '1')
                add10 = 1;
            else if (*src == '7' || *src == '9')
            {
                sprintf(dst, "%s%s", dst, tens[*src-'0'-1]);
                add10 = 1;
            }
            else
                sprintf(dst, *src == '8' && *(src+1) == '0' ? "%s%ss" : "%s%s", dst, tens[*src-'0']);
        }
        else
        {
            if (add10)
            {
                if (*src-'0' <= 6)
                    if (c == '7' && *src == '1')
                        sprintf(dst, "%s et %s", dst, to16[10+*src-'0']);
                    else
                        sprintf(dst, c == '1' ? "%s%s" : "%s-%s", dst, to16[10+*src-'0']);
                else
                    sprintf(dst, c == '1' ? "%sdix-%s" : "%s-dix-%s" , dst, to16[*src-'0']);
                add10 = 0;
            }
            else
                if (*src == '1' && c != 0 && c != '8')
                    sprintf(dst, "%s et 1", dst);
                else if (!(*src == '0' && c != 0))
                    sprintf(dst, c == 0 ? "%s%s" : "%s-%s", dst, to16[*src-'0']);
        }
        c = *src;
    }
    return dst;
}

int main(void)
{
    char *s = "80";
    char res[256] = "";

    printf("%s -> %s\n", s, z0zero(s, res));

    return 0;
}


Citation : Pouet_forever

Fait attention à cette écriture j'ai déjà eu des problèmes. Mets des accolades :)

if (*src-'0' <= 6)
    if (c == '7' && *src == '1')
        sprintf(dst, "%s et %s", dst, to16[10+*src-'0']);
    else
        sprintf(dst, c == '1' ? "%s%s" : "%s-%s", dst, to16[10+*src-'0']);
else
    sprintf(dst, c == '1' ? "%sdix-%s" : "%s-dix-%s" , dst, to16[*src-'0']);

Hmm, pourquoi ? Quel genre de problème as tu eu ?

int main(void)
{
    int i = 2;
    if (i < 5)
        if (i > 2)
            puts("2 < i < 5");
        else
            puts("i <= 2");
    else
        puts("i > 5");

    return 0;
}

i <= 2


Citation : Pouet_forever

Citation : HighTam

(quelle honte :honte: )


Pourquoi ?
On est là pour s'entrainer non ? :)


Ouais, mais je ne pensais pas que j'allais me planter dans cet exercice :lol:
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 23:40:10

Bonsoir,

J'ai bien aimé le sujet, je me suis bien amusé en codant la fonction (qui est près à faire plus inbuvable :-° )
Je gère jusqu'aux quintillons (999 999 999 999 999 999 999 999) et on peut mettre des espaces.

/**
 * Attention : si vous etes sous Linux pensez à liez les fonctions mathématiques avec -lm pour libm.so
 * Attention : if you're under a GNU/Linux system, think to link mathematical functions with -lm for libm.so
 * Ex : gcc -Wall -Wextra -lm main.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define xstr(s) str(s)
#define str(s) #s

#define TAILLE_MAX 100

void
clean_stdin (void) {
    int c;
    while ((c=getchar()) != '\n' && c != EOF);
}

void
trim (char * s) {
    int NbSpace = 0;
    int i, j;
    size_t sLen;
    char * tmp;

    sLen = strlen(s);

    for (i=0 ; s[i] ; ++i) { /* Détermination du nombre d'espaces */
        NbSpace = (s[i] == ' ')? NbSpace+1 : NbSpace;
    }
    if (0 == NbSpace) {
        return;
    }
    tmp = malloc(sLen-NbSpace+1);
    for (i=0, j=0; s[i]; ++i) { /* Création de la nouvelle chaine */
        if (s[i] != ' ') {
            tmp[j] = s[i];
            ++j;
        }
    }
    tmp[sLen-NbSpace] = '\0';

    for (i=0 ; tmp[i] ; ++i) { /* Overwrite sur l'ancien chaine */
        s[i] = tmp[i];
    }
    for(; s[i] ; ++i) { /* On complète avec des 0 pour avoir une chaîne standard */
        s[i] = '\0';
    }
    free(tmp);
}

void
z0zero (char * src, char * dst) {
    const char * unites[10] = {"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf"};
    const char * unites_irr[6] = {"onze", "douze", "treize", "quatorze", "quinze", "seize"};
    const char * dizaines[10] = {"dix", "vingt", "trente", "quarente", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"};
    const char * centaines[8] = {"cent", "mille", "million", "millard", "billion", "trillon", "quatrillon", "quintillon"};
    int index, SIndex, i;
    char srcLen;

    trim(src); /* Suppression des espaces */
    srcLen = strlen(src);

    if (srcLen > 24) {
        fprintf(stderr, "Erreur : Votre nombre est trop grand");
        return;
    }

    /* Multiple de 3 le plus proche */
    if (0 == srcLen%3) {
        index = srcLen/3;
    } else {
        index = floor(srcLen/3.0);
    }
    if (0 == (srcLen-index*3)%3) { /* Le premier chiffre est : */
        SIndex = 3; /* Une centaine */
    } else if (0 == (srcLen-index*3)%2) {
        SIndex = 2; /* Une dizaine */
    } else {
        SIndex = 1; /* Une unite */
    }

    for (i=0 ; src[i];) {
        if (3 == SIndex) {
            int val = src[i]-'0';
            if (val > 0) {
                char buf[50] = {0};
                sprintf(buf, "%s%s%s%s ", (val>1)?unites[val]:"", (val>1)?" ":"" , centaines[0], ('0' == src[i+1] && '0' == src[i+2] && val > 1)? "s" : "");
                strcat(dst, buf);
            }
            ++i;
            --index;
            --SIndex;
        }
        if (2 == SIndex) {
            int val = src[i]-'0';
            if (val > 0) {
                char buf[50];
                sprintf(buf, "%s%s%s", (1 == val && src[i+1]-'0'< 7)? unites_irr[src[i+1]-'0'-1] : dizaines[val-1], (8 == val && '0' == src[i+1])?"s":"", ((7 == val || 9 == val) && (src[i+1]-'0'>6 || '0' == src[i+1]))?"-dix":"");
                strcat(dst, buf);
            }
            if ((1 == val && src[i+1]-'0'< 7) || '0' == src[i+1] || ((7 == val || 9 == val) && '0' == src[i+1])) { /*Faut-il sauter les unites*/
                i += 2;
                SIndex -= 2;
                strcat(dst, " ");
            } else {
                ++i;
                --SIndex;
            }
        }
        if (1 == SIndex) {
            int val = src[i]-'0';
            char buf[50];
            sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0')?"-":"", (i != 0 && 1 == val)?"et-":"", (i != 0 && (7 == src[i-1]-'0' || 9 == src[i-1]-'0') && val < 7)? unites_irr[val-1] : unites[val]);
            strcat(dst, buf);
            ++i;
        }
        if (index > 0 && srcLen > 3 &&(src[i-1] != '0' || src[i-2] != '0' || src[i-3] != '0')) {
            char buf[50] = {0};
            sprintf(buf, "%s%s ", centaines[index], (index >1 && (src[i-1]-'0'>1 || src[i-2]-'0'>1 || src[i-3]-'0'>1))?"s":"");
            strcat(dst, buf);
        }
        SIndex = 3;
    }
}

int
main (void) {
    char * input;
    char NombreEnLettres[500] = {""};
    signed char bool;

    input = malloc(TAILLE_MAX+1);

    /* On s'ocuppe de la saisie de l'utilisateur */
    bool = 0;
    puts("max : 999 999 999 999 999 999 999 999\nexemples: 1 000 000, 1000000");
    while (bool == 0) {
        puts("Saisissez votre nombre :");
        if (scanf(" %"xstr(TAILLE_MAX)"[0-9 ][^\n]", input) == 1) {
            int c;
            if ((c = getchar()) != '\n') { /* Saisie trop longue */
                fprintf(stderr, "Erreur : Nombre trop long\n");
                clean_stdin();
            } else {
                bool = 1;
            }
        } else {
            fprintf(stderr, "Erreur : Echec de la saisie\n");
            clean_stdin();
        }
    }

    z0zero(input, NombreEnLettres);
    printf("%s\n", NombreEnLettres);

    free(input);

    return EXIT_SUCCESS;
}


Si vous avez des remarques, n'hésitez pas.

Edit : Je viens de trouver une bizarrerie je corrige.
Edit2 : Corrigé
Le vieux code :
/**
 * Attention : si vous etes sous Linux pensez à liez les fonctions mathématiques avec -lm pour libm.so
 * Attention : if you're under a GNU/Linux system, think to link mathematical functions with -lm for libm.so
 * Ex : gcc -Wall -Wextra -lm main.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define xstr(s) str(s)
#define str(s) #s

#define TAILLE_MAX 100

void
clean_stdin (void) {
    int c;
    while ((c=getchar()) != '\n' && c != EOF);
}

void
trim (char * s) {
    int NbSpace = 0;
    int i, j;
    size_t sLen;
    char * tmp;

    sLen = strlen(s);

    for (i=0 ; s[i] ; ++i) { /* Détermination du nombre d'espaces */
        NbSpace = (s[i] == ' ')? NbSpace+1 : NbSpace;
    }
    if (0 == NbSpace) {
        return;
    }
    tmp = malloc(sLen-NbSpace+1);
    for (i=0, j=0; s[i]; ++i) { /* Création de la nouvelle chaine */
        if (s[i] != ' ') {
            tmp[j] = s[i];
            ++j;
        }
    }
    tmp[sLen-NbSpace] = '\0';

    for (i=0 ; tmp[i] ; ++i) { /* Overwrite sur l'ancien chaine */
        s[i] = tmp[i];
    }
    for(; s[i] ; ++i) { /* On complète avec des 0 pour avoir une chaîne standard */
        s[i] = '\0';
    }
    free(tmp);
}

void
z0zero (char * src, char * dst) {
    const char * unites[10] = {"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf"};
    const char * unites_irr[6] = {"onze", "douze", "treize", "quatorze", "quinze", "seize"};
    const char * dizaines[10] = {"dix", "vingt", "trente", "quarente", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"};
    const char * centaines[8] = {"cent", "mille", "million", "millard", "billion", "trillon", "quatrillon", "quintillon"};
    int index, SIndex, i;
    char srcLen;

    trim(src); /* Suppression des espaces */
    srcLen = strlen(src);

    if (srcLen > 24) {
        fprintf(stderr, "Erreur : Votre nombre est trop grand");
        return;
    }

    /* Multiple de 3 le plus proche */
    if (0 == srcLen%3) {
        index = srcLen/3;
    } else {
        index = floor(srcLen/3.0);
    }
    if (0 == srcLen%3) { /* Le premier chiffre est : */
        SIndex = 3; /* Une centaine */
    } else if (0 == srcLen%2) {
        SIndex = 2; /* Une dizaine */
    } else {
        SIndex = 1; /* Une unite */
    }

    for (i=0 ; src[i];) {
        if (3 == SIndex) {
            int val = src[i]-'0';
            if (val > 0) {
                char buf[50] = {0};
                sprintf(buf, "%s%s%s%s ", (val>1)?unites[val]:"", (val>1)?" ":"" , centaines[0], ('0' == src[i+1] && '0' == src[i+2] && val > 1)? "s" : "");
                strcat(dst, buf);
            }
            ++i;
            --index;
            --SIndex;
        }
        if (2 == SIndex) {
            int val = src[i]-'0';
            if (val > 0) {
                char buf[50];
                sprintf(buf, "%s%s%s", (1 == val && src[i+1]-'0'< 7)? unites_irr[src[i+1]-'0'-1] : dizaines[val-1], (8 == val && '0' == src[i+1])?"s":"", ((7 == val || 9 == val) && (src[i+1]-'0'>6 || '0' == src[i+1]))?"-dix":"");
                strcat(dst, buf);
            }
            if ((1 == val && src[i+1]-'0'< 7) || '0' == src[i+1] || ((7 == val || 9 == val) && '0' == src[i+1])) { /*Faut-il sauter les unites*/
                i += 2;
                SIndex -= 2;
                strcat(dst, " ");
            } else {
                ++i;
                --SIndex;
            }
        }
        if (1 == SIndex) {
            int val = src[i]-'0';
            char buf[50];
            sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0')?"-":"", (i != 0 && 1 == val)?"et-":"", (i != 0 && (7 == src[i-1]-'0' || 9 == src[i-1]-'0') && val < 7)? unites_irr[val-1] : unites[val]);
            strcat(dst, buf);
            ++i;
        }
        if (index > 0 && srcLen > 2 &&(src[i-1] != '0' || src[i-2] != '0' || src[i-3] != '0')) {
            char buf[50] = {0};
            sprintf(buf, "%s%s ", centaines[index], (index >1 && (src[i-1]-'0'>1 || src[i-2]-'0'>1 || src[i-3]-'0'>1))?"s":"");
            strcat(dst, buf);
        }
        SIndex = 3;
    }
}

int
main (void) {
    char * input;
    char NombreEnLettres[500] = {""};
    signed char bool;

    input = malloc(TAILLE_MAX+1);

    /* On s'ocuppe de la saisie de l'utilisateur */
    bool = 0;
    puts("max : 999 999 999 999 999 999 999 999\nexemples: 1 000 000, 1000000");
    while (bool == 0) {
        puts("Saisissez votre nombre :");
        if (scanf(" %"xstr(TAILLE_MAX)"[0-9 ][^\n]", input) == 1) {
            int c;
            if ((c = getchar()) != '\n') { /* Saisie trop longue */
                fprintf(stderr, "Erreur : Nombre trop long\n");
                clean_stdin();
            } else {
                bool = 1;
            }
        } else {
            fprintf(stderr, "Erreur : Echec de la saisie\n");
            clean_stdin();
        }
    }

    z0zero(input, NombreEnLettres);
    printf("%s\n", NombreEnLettres);

    free(input);

    return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
6 janvier 2010 à 23:45:48

Citation : candide

Par conséquent, on ne sait pas vraiment comment on écrit le nombre 200.000.450 : deux cents millions quatre cent cinquante ou alors deux cent millions quatre cent cinquante ? Moi, je pencherais pour la première écriture (les tranches des 3 chiffres sont indépendantes) plutôt que la 2ème. J'ai consulté plusieurs livres de grammaire et aucun ne traite ce genre d'exemple, ils se contentent d'exemples de nombres ayant 2 ou 3 chiffres et aucun n'utilisent de millions ou de milliards.



Après multiples recherches sur le net il se trouve que l'avis est partagé ...
Si on en crois ce site on y mettrait un 's' -> "deux milliards cinq cents millions trois cent mille deux cent cinquante-trois".
Si on en crois celui-là on n'en mettrait pas -> "cinquante et un milliards neuf cent soixante-treize millions quatre cent soixante-deux mille quarante-neuf".

Donc avis partagé. Il faudrait fixer une règle pour l'exo pour que tout le monde s'en tienne :)

Personnellement je suis pour la deuxième écriture :)

@ Lithrein :

Ta fonction trim est inutilement compliquée je trouve (appel à malloc, strlen, free).
Tu pourrais avoir 2 indices : Un qui parcoures ta chaîne et un autre qui pointe sur l'endroit où mettre ton caractère. Si tu rencontres un espace tu n'incrémentes pas ton 2ème indice :)
Pourquoi faire un malloc dans ton main ? tu peux très bien faire avec un tableau statique :)

Tout imbriquer dans des sprintf comme ça je trouve ça complètement illisible.

Après tu as quelques bugs :

80000
huit mille  -mille

1000
quintillon mille mille

2000
vingt mille mille
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 0:02:40

Citation : ttthebest

ici il est suivi d'un autre nombre, millions.



Non justement, million (de même que milliard) n'est pas un nombre au même titre que 42, d'ailleurs il s'accorde systématiquement. Par contre mille est un nombre (et c'est peut-être pour ça que l'on accorde pas cent dans deux cent mille). Ici, dans la terminologie de l'Académie, je dirais que million est un nom.

Citation : Pouet_forever


Après multiples recherches sur le net il se trouve que l'avis est partagé ...
Si on en crois ce site on y mettrait un 's' -> "deux milliards cinq cents millions trois cent mille deux cent cinquante-trois".
Si on en crois celui-là



Merci de cette recherche efficace.

Citation : Pouet_forever

on n'en mettrait pas -> "cinquante et un milliards neuf cent soixante-treize millions quatre cent soixante-deux mille quarante-neuf".



Cet exemple est correct mais je ne vois pas ce qu'il prouve dans le cas qui nous intéresse.
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 0:04:47

@Poeut_forever : Pour la fonction trim je suis d'accord qu'il faut que je la refasse.
Par contre, le bug du 80 000 est corrigé.
Il reste un bug (qui sera vite corrigé):
`1000` donne `un mille`
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 0:17:03

Citation : candide

Cet exemple est correct mais je ne vois pas ce qu'il prouve dans le cas qui nous intéresse.



Le fait qu'il n'y ai pas de 's' après le cent de "neuf cent soixante-treize" :)

Je viens de trouver un site met tout au clair et ne laisse aucun ambiguïté :

Citation : AIDENET <== Click on me

Vingt ne prend un S que dans "quatre-vingts"
s'il n'est suivi d'aucun autre chiffre ou nombre,

c'est-à-dire quand il termine un nombre.

Cent ne prend un S que lorsqu'il est multiplié
et s'il n'est suivi d'aucun autre chiffre ou nombre,

c'est-à-dire quand il termine un nombre.



@ Lithrein : Le 80 000 n'est pas bon encore :p
Il ne s'accorde que s'il n'est pas suivi :)

80000
quatre-vingts mille


Quand les nombres sont suivi de "mille" ils ne s'accordent pas :

600000
six cents  mille

10000000
quintillon million


Edit : Je me suis amusé à rajouter les billons trillions et compagnie à mon code ^^

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ============ Variables globales ============ */
#pragma mark -
#pragma mark globales

char const * const unites [20] = {
	"zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
	"dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"
};

char const * const dizaines [10] = {
	"", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante",
	"quatre-vingt", "quatre-vingt"
};

char const * const centaines [] = {
	"mille", "million", "milliard", "billion", "trillon", "quatrillon", "quintillon"
};

/* ============ Fonctions ============ */
#pragma mark -

/* Fonction qui prend en argument 1 nombre entre 0 et 99 (tous 2 inclus).
 * Une chaîne de caractère 'str' dans laquelle on va mettre la décomposition du nombre.
 * Un paramètre 'mil' pour savoir si le nombre est 1000 (mille).
 */

void dix(int nb, char *str, int mil, int esse) {
	char tmp[100] = "";
	int unit = nb % 10;
	int disse = nb / 10;
	
	if (nb == 0)
		return;
	
	if (nb == 1 && mil == 1)
		return;
	
	if (nb < 20) {
		strcat(str, unites[nb]);
		strcat(str, " ");
		return;
	}
	
	if (nb == 80) {
		strcat(str, dizaines[disse]);
		if (mil || !esse)
			strcat(str, " ");
		else
			strcat(str, "s ");
		return;
	}
	
	strcat(tmp, dizaines[disse]);
	
	if (unit == 1 && disse != 8 && disse != 9)
		strcat(tmp, " et ");
	else if (unit != 0)
		strcat(tmp, "-");
	else
		strcat(tmp, " ");
	
	if (disse == 7 || disse == 9)
		strcat(tmp, unites[unit+10]);
	else if (unit != 0)
		strcat(tmp, unites[unit]);
	
	strcat(str, tmp);
	strcat(str, " ");
}

/* Fonction qui décompose la centaine du nombre.
 * La fonction prend un nombre sur 3 chiffres 0 <= nb <= 999.
 * Les autres sont les mêmes paramètres que la fonction dix.
 */

void cent(int nb, char *str, int mil, int esse) {
	char tmp[100] = "";
	
	if (nb > 99) {
		int mod = nb / 100;
		
		if (mod > 1)
			sprintf(tmp, "%s ", unites[mod]);
		strcat(tmp, "cent");
		
		if (esse && !mil && mod > 1 && nb % 100 == 0)
			strcat(tmp, "s");
		strcat(tmp, " ");
	}
	
	dix(nb % 100, tmp, mil, esse);
	
	strcpy(str, tmp);
}

/* Fonction qui prend une chaîne qui contient le nombre à décomposer.
 * Retourne le nombre en toutes lettres.
 */

char * z0zero(char const *src) {
	static char res[500];
	char str[500] = "";
	int i, j;
	int len = strlen(src);
	int tmp, mult;
	int mil = 0, esse = 1;
	
	if (strtol(src, NULL, 10) == 0) {
		sprintf(res, "%s", unites[0]);
		return res;
	}
	
	/* On parcoures notre tableau 'centaine'.
	 * 0 == "cent", 1 == "mille", 2 == "million", 3 == "milliard", etc.
	 */
	for (j = 0; j < 8; j++) {
		tmp = 0;
		mult = 1;
		*str = '\0';
		/* Si le nombre est mille ou pas.
		 * "mille" est invariable, c'est pour le 's'. */
		if (j == 1)
			mil = 1;
		else
			mil = 0;
		
		for (i = len-1-(3*j); i >= 0 && i >= len-3*(j+1); i--, mult*=10)
			tmp += (src[i] - '0') * mult;
		
		cent(tmp, str, mil, esse);
		
		if (j != 0 && tmp != 0) {
			strcat(str, centaines[j-1]);
			if (tmp != 1 && j != 1)
				strcat(str, "s ");
			else
				strcat(str, " ");
		}
		
		strcat(str, res);
		strcpy(res, str);
		
		if (i < 0)
			break;
		if (tmp != 0)
			esse = 0;
	}
	
	return res;
}

/* 999 999 999 999 999 */

int main(void) {
	char * str = "999999999999999999999999";
	
	printf("%s -> ", str);
	printf("%s", z0zero(str));
	return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 0:29:43

Rhaa, J'ai lu trop vite les exceptions.
Heureusement que cela ne concerne que mille.
*Retourne corriger ses fautes d'accords*
Je ferais ça demain.
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 0:49:41

Citation : Pouet_forever


Le fait qu'il n'y ai pas de 's' après le cent de "neuf cent soixante-treize"



Ça je ne le conteste pas, ce n'est pas le problème : ici, on a un nombre à trois chiffres et neuf cent est suivi du nombre soixante-treize donc la règle est claire, il n'y a pas d'accord.



Citation : Pouet_forever


Je viens de trouver un site met tout au clair et ne laisse aucun ambiguïté



Bof, j'ai un doute sur la rigueur rédactionnelle de cette page. Aucun de leur exemple ne sort du cadre usuel et passe-partout donc j'ai toutes les raisons de penser que leur règle (qu'ils tiennent d'où d'ailleurs ?) ne concerne aucune situation plus complexe que celle posée par un nombre de deux ou trois chiffres.

Même si l'écriture des nombres n'est pas toujours logique, ce qui me semble le moins illogique c'est de considérer qu'un "grand" nombre est construit par l'agglomération de petits nombres ie de nombres inférieurs à 1000 et donc chaque tranche suivie de million ou milliard est autonome et ignore donc ce qui suit. Pour résumer, on applique la règle de construction des nombres à trois chiffres et on concatène de tels nombres (le cas de 1000 étant particulier car mille n'est pas un nom comme million puisqu'on ne dit pas "un mille" comme on dit "un million").
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 1:16:44

@artificier59
merci du conseil ;)

@GurneyH
merci pour l info c'est vraiement super, par contre je me suis stoper car j ai du mal à bien saisir printf et scanf...
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 1:59:52

Bon je fais ma dernière intervention et après j'arrête à ce sujet.
Depuis le début on cherche la petite bête mais en fait il n'y en a pas. Je pense que la définition de l'académie est claire et qu'il n'y a pas besoin d'épiloguer là-dessus :

Citation : Académie française <== Click on me

Vingt et cent se terminent par un s quand ils sont précédés d’un nombre qui les multiplie, mais ils restent invariables s’ils sont suivis d’un autre nombre ou de mille.



Si cent ou vingt est suivi d'un autre nombre il ne s'accorde pas : 200 000 001 ne s'accorde pas -> deux cent millions un.
Si il n'est pas suivi d'un autre nombre il s'accorde : 200 000 000 -> deux cents millions.
Si il est suivi de mille il ne s'accorde pas : 200 000 -> deux cent mille.

Même chose pour quatre-vingts :

80 000 001 -> quatre-vingt millions un.
80 000 000 -> quatre-vingts millions.
80 000 -> quatre-vingt mille.

Donc pour répondre à ce que tu as dis : Non chaque groupe de nombre n'est pas autonome. Que ce soit logique ou que ça ne le soit pas ce n'est plus de mon (notre) ressort.
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 2:25:54

Citation : Pouet_forever



Si cent ou vingt est suivi d'un autre nombre il ne s'accorde pas : 200 000 001 ne s'accorde pas -> deux cent millions un.



Non, ce n'est pas le cas ici : vingt n'est pas suivi d'un autre nombre puisqu'il est suivi du mot "millions"

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
7 janvier 2010 à 2:34:30

Euh, x) à la base on doit faire un programme qui affiche un nombre numérique donné, en un nombre en lettres, et là c'est parti sur un cours de français...LOL ?
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 2:42:30

Citation : Geek0

Euh, x) à la base on doit faire un programme qui affiche un nombre numérique donné, en un nombre en lettres, et là c'est parti sur un cours de français...LOL ?



Comment veut-tu faire un programme correct si tu ne connais pas la bonne syntaxe ? ;)
C'est un peut comme si tu programmais avec des mots-clés en majuscule :) (bon l'exemple est peut-être mal trouvé mais l'idée est là ^^ )
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
7 janvier 2010 à 2:45:23

Nan, mais c'est le programme qui renvoit la chaîne, pas le contraire, mais bon tu as raison ^^
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 8:21:12

Citation : candide

Non, ce n'est pas le cas ici : vingt n'est pas suivi d'un autre nombre puisqu'il est suivi du mot "millions"



Pour clore le débat, la réponse donnée par Le Conjugueur est celle-ci :

Citation : Le Conjugueur <== Click on me

200 000 001 s'écrit : deux cents millions un
200 000 000 s'écrit : deux cents millions
201 000 000 s'écrit : deux cent un millions
200 000 s'écrit : deux cent mille

80 000 001 s'écrit : quatre-vingts millions un
80 000 000 s'écrit : quatre-vingts millions
81 000 000 s'écrit : quatre-vingt-un millions
80 000 s'écrit : quatre-vingt mille



Je pense qu'il serait bon que GurneyH le rajoute à son exercice pour que tout le monde parte sur la même base ;)

Imaginez, nous, qui sommes français, ne savons pas écrire correctement les nombres, alors imaginez le mal que les étrangers ont à apprendre cette langue :o
  • Partager sur Facebook
  • Partager sur Twitter
7 janvier 2010 à 8:24:16

Citation : Pouet_forever

alors imaginez le mal que les étrangers ont à apprendre cette langue :o


Je confirme :lol:
  • Partager sur Facebook
  • Partager sur Twitter