Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercices pour débutants en C

Au menu : zSommeChiffres (nombres, algo)

8 janvier 2010 à 22:40:02

C'est fait depuis hier nan ? :-°
  • Partager sur Facebook
  • Partager sur Twitter
8 janvier 2010 à 22:47:23

Citation : shareman

C'est fait depuis hier nan ? :-°


Je n'avais pas fait attention... Désolé!
Merci. :)
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
9 janvier 2010 à 0:36:52

Citation : Pouet_forever


Dîtes moi si vous voyez des erreurs :)



Allez, courage, encore quelques petits efforts ;) :


pouet.c:170:36: attention : « /* » à l'intérieur d'un commentaire
pouet.c:171:35: attention : « /* » à l'intérieur d'un commentaire
pouet.c:172:32: attention : « /* » à l'intérieur d'un commentaire
390000000 -> trois cent quatre-vingtdix millions
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 0:43:32

Bien vu ^^
C'est édité :)

Pour les commentaires c'était fait exprès, c'était pour tester plusieurs nombres sans me faire trop ch*** :D

Qu'est-ce que tu penses du code maintenant ? :)
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 0:55:10

Citation : Pouet_forever


Qu'est-ce que tu penses du code maintenant ? :)




Très bien. Mais je crois que je préfère encore celui de Gurney car j'aime bien les choses faites très simplement, juste affaire de goût personnel.
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 1:08:21

Ok merci :)
Après c'est vrai chacun son goût, mais j'aime bien aussi les choses faites simplement :)
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 16:36:33

Citation : Pouet_forever


Qu'est-ce que tu penses du code maintenant ? :)



Je suis en train d'essayer de tester un peu plus sérieusement que précédemment la validité de tes sorties ce qui me conduit à me pencher sur ton code C. Alors, il y a deux choses qui me paraissent à revoir du point de vue du C :

1) l'utilisation d'une variable statique dans ta fonction z0zero() ne me parait pas bonne : en effet, l'action de ta fonction n'est pas uniforme puisqu'à son premier appel l'espace qui recueille la chaîne en lettres est initialisé à 0 (à cause de la variable statique) mais pas à un éventuel appel ultérieur où l'ancienne chaîne est conservée. Si ton code n'a pas été pensé pour cela, il risque de planter. Personnellement, j'utiliserais plutôt calloc() ou alors une autre interface pour la fonction z0zero().

2) Ta fonction z0zero() au travers de ta fonction supp_espaces() modifie la chaîne donnée en entrée. Or rien n'assure que cet espace est modifiable. Résultat des courses : je teste ton code et je me retrouve avec un segfault.

  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 18:38:02

Voilà c'est modifié :)
J'initialise ma variable statique à chaque appel de fonction.
Je copie le tableau passé en paramètre pour éviter le segfault.
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 18:58:45

Citation : Pouet_forever

Voilà c'est modifié :)



Pour que tout le monde y ait accès, donne un lien vers la discussion où ton code modifié est placé.

Citation : Pouet_forever


Je copie le tableau passé en paramètre pour éviter le segfault.



OK, plus de segfault. J'ai quand même trouvé de petites erreurs de sortie :

*) 70
*) Un espace inutile à la fin de par exemple 5000 ou 5700000.

J'ai placé dans ton code une liste de nombres à traiter :

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


/* Fonction qui supprime les espaces et les 0 en trop. */

void supp_espaces(char *src, char *str) {
	int i, j;
	int zero = 1;
	for (i=j = 0; src[i] != '\0' && j < LEN_MAX_100-1; i++) {
		str[j] = src[i];
		if (src[i] != '0')
			zero = 0;
		else if (src[i] == '0' && zero) {
			continue;
		}
		if (src[i] != ' ')
			j++;
	}
	str[j] = '\0';
}

/* Fonction qui vérifie si le nombre est zéro.
 * Renvoie 1 si le nombre est 0, 0 dans le cas contraire. */

int estZero(char *str) {
	for ( ; *str; str++)
		if (*str != '0')
			return 0;
	return 1;
}

/* Conerti 'i' lettres en nombre. */ 

int convert(char * (*str), int i) {
	int tmp = 0;
	int j;
	
	for (j = 0; j < i && **str; j++, (*str)++) {
		tmp *= 10;
		tmp += **str - '0';
	}
	return tmp;
}

/* Fonction qui renvoie dans 'str' la décomposition du nombre 0 <= nb <= 99 */

void dix(int nb, char *str) {
	char const * const dizaines [10] = {
		"", "dix", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante",
		"quatre-vingt", "quatre-vingt"
	};
	char const * const unites [20] = {
		"", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf",
		"dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"
	};
	
	char tmp[LEN_MAX_100] = "";
	ldiv_t div = ldiv(nb, 10);
	
	if (nb == 0)
		return;
	
	if (nb >= 20)
		strcat(tmp, dizaines[div.quot]);
	
	if (div.rem == 1 && nb >= 20 && div.quot != 8 && div.quot != 9)
		strcat(tmp, " et ");
	else if ((div.rem || nb == 90) != 0 && nb >= 20)
		strcat(tmp, "-");
	
	if ((nb >= 10 && nb < 20) || div.quot == 7 || div.quot == 9)
		strcat(tmp, unites[div.rem+10]);
	else if (div.rem != 0)
		strcat(tmp, unites[div.rem]);
	
	strcat(str, tmp);
}

/* Décompose la centaine du nombre. 0 <= nb <= 999 */

void cent(int nb, char *str) {
	char tmp[LEN_MAX_100] = "";
	ldiv_t div = ldiv(nb, 100);
	
	if (nb > 99) {
		if (div.quot > 1) {
			dix(div.quot, tmp);
			strcat(tmp, " ");
		}
		strcat(tmp, "cent");
		if (div.rem != 0)
			strcat(tmp, " ");
	}
	
	dix(div.rem, tmp);
	
	strcpy(str, tmp);
}

/* Décompose les nombres au dessus de la centaine 0 <= nb <= inf */

void mille(char *res, char *src, ldiv_t div) {
	enum { CENT, MILLE };
	char const * const centaines [7] = {
		"mille", "million", "milliard", "billion", "trillion", "quatrillion", "quintillion"
	};
	char str[LEN_MAX_500] = "";
	int i, tmp;
	ldiv_t div_tmp;
	
	for (i = div.quot; i >= 0; i--) {
		
		tmp = convert(&src, div.rem);
		/* Tout le reste est obligatoirement basé sur 3 chiffres. */
		div.rem = 3;
		
		div_tmp = ldiv(tmp, 100);
		*str = '\0';
		
		if (i != MILLE || (i == MILLE && tmp != 1))
			cent(tmp, str);
		strcat(res, str);
		
		/* Si le nombre = 0 on ne fait rien.
		 * Si le nombre n'est pas mille et se fini par 80 ou ...
		 * ... si le nombre est une centaine entière on met un 's'. */
		if (i != MILLE &&
			((div_tmp.quot > CENT+1 && div_tmp.rem == CENT) || (tmp != 0 && div_tmp.rem == 80)))
			strcat(res, "s");
		
		if (i != CENT && tmp != 0) {
			/* Si le nombre est != de 1000 on met un espace */
			if (i != MILLE || (i == MILLE && tmp != 1))
				strcat(res, " ");
			strcat(res, centaines[i-1]);
			if (i != MILLE && tmp > 1)
				strcat(res, "s");
			strcat(res, " ");
		}
	}
}

char * z0zero(char *src) {
	static char res[LEN_MAX_500];
	char tmp[LEN_MAX_100] = "";
	int len;
	ldiv_t div;
	
	*res = '\0';
	supp_espaces(src, tmp);
	
	if (estZero(tmp)) {
		sprintf(res, "%s", "zero");
		return res;
	}
	
	len = strlen(tmp);
	if (len > 8*3) {
		sprintf(res, "%s", "Erreur: Nombre trop grand.");
		return res;
	}
	div = ldiv(len, 3);
	
	if (div.rem == 0) {
		div.quot--;
		div.rem = 3;
	}
	
	mille(res, tmp, div);
	
	return res;
}


int main(void) {
  char *x[] =
    { "0", "1", "2", "3", "4", "5", "7", "8", "9", "10", "11", "12", "13",
    "14", "15", "16", "17", "18", "19", "20", "21", "29", "30", "40", "42",
    "51",
    "60", "69", "70", "71", "77", "80", "81", "85", "90", "91", "99", "100",
    "101",
    "110", "130", "173", "196", "200", "205", "217", "223", "256", "268",
    "273",
    "280", "297", "734", "1000", "1001", "1017", "1020", "1032", "1111",
    "2000",
    "2100", "2200", "3003", "3780", "10000", "10005", "10900", "11000",
    "11700",
    "12000", "18805", "61400", "77010", "80000", "80078", "90000", "92002",
    "97459",
    "100000", "100007", "204003", "310857", "700005", "1000000", "2000000",
    "2001001",
    "72424600", "79828480", "200000000", "708000000", "1000000000", "2000000000",
    "2000500000",     "2000780001"
  };
  int i, n = sizeof x / sizeof *x;

  for (i = 0; i < n; i++)
    {
      printf("%s.\n",   z0zero(x[i]));
    }
	return EXIT_SUCCESS;
}


EDIT Le point dans l'affichage sert juste à visualiser la présence d'un éventuel espace.
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 19:24:23

C'est modifié :)

J'espère que c'est bon cette fois :p
Le code est ici !
  • Partager sur Facebook
  • Partager sur Twitter
9 janvier 2010 à 19:56:54

Citation : Pouet_forever


J'espère que c'est bon cette fois :p



Je viens de comparer tes sorties aux miennes pour tous les entiers entre 0 et 3 millions et nous obtenons exactement les mêmes résultats.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 5:51:37

Mon programme rajoutais dans certains cas un espace inutile à la fin.
J'oubliais parfois un s à million, milliard. :-° .
J'avais également un problème parfois, à cause de ma chaîne s_q[4]... Je l'ai déplacée a l'intérieur de la boucle.
C'est corrigé. :)

char *z0zero(char *src, char *dst)
{
    char const *s_p3[] =
    {
        "mille", "million", "milliard"
    };
    int n;
    src = sauterZeros(src);
    n = strlen(src);
    if (n == 0)
        nombre1chiffre(dst, 0);
    else
    {
        int q, r;
       
        while (n > 3)
        {
            char s_q[4] = {0};
            int nq;
            int p = n / 3;
            if (n % 3 == 0)
                p--;

            nq = n - p * 3;

            strncpy(s_q, src, nq);
            q = strtol(s_q, NULL, 10);
            r = strtol(src + nq, NULL, 10);
            nombre3chiffres(dst, q, p);
            if(q > 1 || p != 1)
                strcat(dst, " ");
            strcat(dst, s_p3[p - 1]);
            if(p != 1 && q > 1)
                strcat (dst, "s");
            if(r != 0)
                strcat(dst, " ");
            src = sauterZeros(src + nq);
            n = strlen(src);
        }

        if (n > 0)
            nombre3chiffres(dst, strtol(src, NULL, 10), 0);
    }
    return dst;
}


J'ai pu me lancer dans les tests. :pirate:
@Lithrein: ton programme rajoute systématiquement un espace inutile.
Une fois cet espace supprimé, j'ai testé, tu as un problème avec les nombres du type
1001000 -> (sortie de ta fonction) un million un mille

@Pouet: j'ai comparé les sorties de nos 2 codes (merci les unsigned long long), et les seules différences venait de problèmes dans le mien. J'ai pu corrigé.
Chapeau. :)
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
10 janvier 2010 à 11:21:18

Citation : GurneyH

@Lithrein: ton programme rajoute systématiquement un espace inutile.
Une fois cet espace supprimé, j'ai testé, tu as un problème avec les nombres du type
1001000 -> (sortie de ta fonction) un million un mille


Merci, c'est corrigé.
Pour l'espace, c'est corrigé à la barbare (strcat(dst, "\b") :-° ) mais de toutes façons je vais refaire ma solution car elle est vraiment obscure par rapport à vos codes sources très clairs.
Je me demande si je ne vais pas le proposer ici :p

/**
 * Attention : si vous etes sous GNU/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
 * Todo : fixer : bug espace
 */
#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);
}

char*
removeZeroes (char * s) {
    size_t sLen = strlen(s), i = 0;
    while ('0' == s[i] && i != sLen-1)
        ++i;

    return s+i;
}

void
trim (char * s) {
    int i, j;

    for (i=j = 0; s[i] != '\0'; i++) {
        s[j] = s[i];
        if (s[i] != ' ')
            j++;
    }
    s[j] = '\0';
}

char*
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", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"};
    const char * centaines[8] = {"cent", "mille", "million", "milliard", "billion", "trillion", "quatrillion", "quintillion"};
    int index, SIndex, i;
    char srcLen;

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

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

    /* 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], (index != 2 && '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'> 0 && src[i+1]-'0'< 7)? unites_irr[src[i+1]-'0'-1] : dizaines[val-1], (index != 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*/
                    strcat(dst, " ");
                }
            }
            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;
            } else {
                ++i;
                --SIndex;
            }
        }
        if (1 == SIndex) {
            int val = src[i]-'0';
            if (!(strlen(src+i) == 4 && val == 1)) {
                char buf[50];
                sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0' && (val != 1 || (1 == val && (src[i-1]-'0' == 8 || src[i-1]-'0' == 9))))?"-":"", (i != 0 && 1 == val && src[i-1] != '0' && src[i-1]-'0' != 8 && src[i-1]-'0' != 9)?" 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'>0 || src[i-3]-'0'>0))?"s":"");
            strcat(dst, buf);
        }
        SIndex = 3;
    }
    strcat(dst, "\b");

    return dst;
}

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

    /* 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);
    if (NombreEnLettres != NULL)
        printf("%s.\n", NombreEnLettres);

    return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 13:05:20

Citation : Lithrein

Pour l'espace, c'est corrigé à la barbare (strcat(dst, "\b") :-° )


lol ! :lol:
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 16:59:40

Citation : Lithrein

mais de toutes façons je vais refaire ma solution car elle est vraiment obscure par rapport à vos codes sources très clairs.



Pour une raison que j'ignore, je n'arrive pas à tester ton code avec ma liste de nombres, j'obtiens un segfault :

/**
 * Attention : si vous etes sous GNU/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
 * Todo : fixer : bug espace
 */
#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);
}

char*
removeZeroes (char * s) {
    size_t sLen = strlen(s), i = 0;
    while ('0' == s[i] && i != sLen-1)
        ++i;

    return s+i;
}

void
trim (char * s) {
    int i, j;

    for (i=j = 0; s[i] != '\0'; i++) {
        s[j] = s[i];
        if (s[i] != ' ')
            j++;
    }
    s[j] = '\0';
}

char*
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", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"};
    const char * centaines[8] = {"cent", "mille", "million", "milliard", "billion", "trillion", "quatrillion", "quintillion"};
    int index, SIndex, i;
    char srcLen;

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

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

    /* 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], (index != 2 && '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'> 0 && src[i+1]-'0'< 7)? unites_irr[src[i+1]-'0'-1] : dizaines[val-1], (index != 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*/
                    strcat(dst, " ");
                }
            }
            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;
            } else {
                ++i;
                --SIndex;
            }
        }
        if (1 == SIndex) {
            int val = src[i]-'0';
            if (!(strlen(src+i) == 4 && val == 1)) {
                char buf[50];
                sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0' && (val != 1 || (1 == val && (src[i-1]-'0' == 8 || src[i-1]-'0' == 9))))?"-":"", (i != 0 && 1 == val && src[i-1] != '0' && src[i-1]-'0' != 8 && src[i-1]-'0' != 9)?" 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'>0 || src[i-3]-'0'>0))?"s":"");
            strcat(dst, buf);
        }
        SIndex = 3;
    }
    strcat(dst, "\b");

    return dst;
}

int
main (void) {

  char *x[] =
    { "0", "1", "2", "3", "4", "5", "7", "8", "9", "10", "11", "12", "13",
    "14", "15", "16", "17", "18", "19", "20", "21", "29", "30", "40", "42",
    "51",
    "60", "69", "70", "71", "77", "80", "81", "85", "90", "91", "99", "100",
    "101",
    "110", "130", "173", "196", "200", "205", "217", "223", "256", "268",
    "273",
    "280", "297", "734", "1000", "1001", "1017", "1020", "1032", "1111",
    "2000",
    "2100", "2200", "3003", "3780", "10000", "10005", "10900", "11000",
    "11700",
    "12000", "18805", "61400", "77010", "80000", "80078", "90000", "92002",
    "97459",
    "100000", "100007", "204003", "310857", "700005", "1000000", "2000000",
    "2001001",
    "72424600", "80000000", "79828480", "200000000", "708000000",
    "1000000000", "2000000000",
    "2000500000", "2000780001", "111111111111", "990990990990"
  };
  int i, n = sizeof x / sizeof *x;

  for (i = 0; i < n; i++)
    {
        char NombreEnLettres[500] = {""};

          z0zero(x[i], NombreEnLettres);
    if (NombreEnLettres != NULL)
        printf("%s.\n", NombreEnLettres);

    }

    return EXIT_SUCCESS;
}


candide@candide-desktop:~$ gcc -O2 -W -Wall -std=c99 -pedantic -o x lithrein.c -lm
candide@candide-desktop:~$ ./x
Erreur de segmentation
candide@candide-desktop:~$



Après avoir ouvert mon débogueur, je me rends compte que tu as fait la même erreur que pouet (tu modifies une entrée en écrivant dans un zone qui se trouve interdite en écriture).

Après avoir retiré ce qui plantait (et qui franchement n'apporte pas grand chose si ce n'est des erreurs à gérer ;) ), je me rends compte qu'il y a au moins une erreur :



un millions.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 17:56:07

Citation : candide


Après avoir retiré ce qui plantait (et qui franchement n'apporte pas grand chose si ce n'est des erreurs à gérer ;) ), je me rends compte qu'il y a au moins une erreur :


un millions.



J'ai
1000000 -> un million

avec la solution de Lithrein...
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
10 janvier 2010 à 18:00:14

Citation : candide

Citation : Lithrein

mais de toutes façons je vais refaire ma solution car elle est vraiment obscure par rapport à vos codes sources très clairs.



Pour une raison que j'ignore, je n'arrive pas à tester ton code avec ma liste de nombres, j'obtiens un segfault :


/**
 * Attention : si vous etes sous GNU/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
 * Todo : fixer : bug espace
 */
#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);
}

char*
removeZeroes (char * s) {
    size_t sLen = strlen(s), i = 0;
    while ('0' == s[i] && i != sLen-1)
        ++i;

    return s+i;
}

void
trim (char * s) {
    int i, j;

    for (i=j = 0; s[i] != '\0'; i++) {
        s[j] = s[i];
        if (s[i] != ' ')
            j++;
    }
    s[j] = '\0';
}

char*
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", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"};
    const char * centaines[8] = {"cent", "mille", "million", "milliard", "billion", "trillion", "quatrillion", "quintillion"};
    int index, SIndex, i;
    char srcLen;

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

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

    /* 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], (index != 2 && '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'> 0 && src[i+1]-'0'< 7)? unites_irr[src[i+1]-'0'-1] : dizaines[val-1], (index != 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*/
                    strcat(dst, " ");
                }
            }
            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;
            } else {
                ++i;
                --SIndex;
            }
        }
        if (1 == SIndex) {
            int val = src[i]-'0';
            if (!(strlen(src+i) == 4 && val == 1)) {
                char buf[50];
                sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0' && (val != 1 || (1 == val && (src[i-1]-'0' == 8 || src[i-1]-'0' == 9))))?"-":"", (i != 0 && 1 == val && src[i-1] != '0' && src[i-1]-'0' != 8 && src[i-1]-'0' != 9)?" 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'>0 || src[i-3]-'0'>0))?"s":"");
            strcat(dst, buf);
        }
        SIndex = 3;
    }
    strcat(dst, "\b");

    return dst;
}

int
main (void) {

  char *x[] =
    { "0", "1", "2", "3", "4", "5", "7", "8", "9", "10", "11", "12", "13",
    "14", "15", "16", "17", "18", "19", "20", "21", "29", "30", "40", "42",
    "51",
    "60", "69", "70", "71", "77", "80", "81", "85", "90", "91", "99", "100",
    "101",
    "110", "130", "173", "196", "200", "205", "217", "223", "256", "268",
    "273",
    "280", "297", "734", "1000", "1001", "1017", "1020", "1032", "1111",
    "2000",
    "2100", "2200", "3003", "3780", "10000", "10005", "10900", "11000",
    "11700",
    "12000", "18805", "61400", "77010", "80000", "80078", "90000", "92002",
    "97459",
    "100000", "100007", "204003", "310857", "700005", "1000000", "2000000",
    "2001001",
    "72424600", "80000000", "79828480", "200000000", "708000000",
    "1000000000", "2000000000",
    "2000500000", "2000780001", "111111111111", "990990990990"
  };
  int i, n = sizeof x / sizeof *x;

  for (i = 0; i < n; i++)
    {
        char NombreEnLettres[500] = {""};

          z0zero(x[i], NombreEnLettres);
    if (NombreEnLettres != NULL)
        printf("%s.\n", NombreEnLettres);

    }

    return EXIT_SUCCESS;
}


candide@candide-desktop:~$ gcc -O2 -W -Wall -std=c99 -pedantic -o x lithrein.c -lm
candide@candide-desktop:~$ ./x
Erreur de segmentation
candide@candide-desktop:~$




Après avoir ouvert mon débogueur, je me rends compte que tu as fait la même erreur que pouet (tu modifies une entrée en écrivant dans un zone qui se trouve interdite en écriture).

Après avoir retiré ce qui plantait (et qui franchement n'apporte pas grand chose si ce n'est des erreurs à gérer ;) ), je me rends compte qu'il y a au moins une erreur :



un millions.


Pour la fonction trim, il faudra que je corrige, mais par contre pour obtenir `un millons` tu mets quoi en entrée par ce que chez moi, il n'y a pas de problème.
$ ./Lithrein_z0zero
max : 999 999 999 999 999 999 999 999
exemples: 1 000 000, 1000000
Saisissez votre nombre :
1 000 000
un million.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 18:07:23

Citation : Lithrein

mais par contre pour obtenir `un millons` tu mets quoi en entrée par ce que chez moi, il n'y a pas de problème.



Réponse :


/**
 * Attention : si vous etes sous GNU/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
 * Todo : fixer : bug espace
 */
#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 i, j;

    for (i=j = 0; s[i] != '\0'; i++) {
        s[j] = s[i];
        if (s[i] != ' ')
            j++;
    }
    s[j] = '\0';
}

char*
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", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"};
    const char * centaines[8] = {"cent", "mille", "million", "milliard", "billion", "trillion", "quatrillion", "quintillion"};
    int index, SIndex, i;
    char srcLen;

    srcLen = strlen(src);

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

    /* 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], (index != 2 && '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'> 0 && src[i+1]-'0'< 7)? unites_irr[src[i+1]-'0'-1] : dizaines[val-1], (index != 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*/
                    strcat(dst, " ");
                }
            }
            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;
            } else {
                ++i;
                --SIndex;
            }
        }
        if (1 == SIndex) {
            int val = src[i]-'0';
            if (!(strlen(src+i) == 4 && val == 1)) {
                char buf[50];
                sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0' && (val != 1 || (1 == val && (src[i-1]-'0' == 8 || src[i-1]-'0' == 9))))?"-":"", (i != 0 && 1 == val && src[i-1] != '0' && src[i-1]-'0' != 8 && src[i-1]-'0' != 9)?" 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'>0 || src[i-3]-'0'>0))?"s":"");
            strcat(dst, buf);
        }
        SIndex = 3;
    }
    strcat(dst, "\b");

    return dst;
}

int
main (void) {

  char *x[] =
    { "0", "1", "2", "3", "4", "5", "7", "8", "9", "10", "11", "12", "13",
    "14", "15", "16", "17", "18", "19", "20", "21", "29", "30", "40", "42",
    "51",
    "60", "69", "70", "71", "77", "80", "81", "85", "90", "91", "99", "100",
    "101",
    "110", "130", "173", "196", "200", "205", "217", "223", "256", "268",
    "273",
    "280", "297", "734", "1000", "1001", "1017", "1020", "1032", "1111",
    "2000",
    "2100", "2200", "3003", "3780", "10000", "10005", "10900", "11000",
    "11700",
    "12000", "18805", "61400", "77010", "80000", "80078", "90000", "92002",
    "97459",
    "100000", "100007", "204003", "310857", "700005", "1000000", "2000000",
    "2001001",
    "72424600", "80000000", "79828480", "200000000", "708000000",
    "1000000000", "2000000000",
    "2000500000", "2000780001", "111111111111", "990990990990"
  };
  int i, n = sizeof x / sizeof *x;

  for (i = 0; i < n; i++)
    {
        char NombreEnLettres[500] = {""};

          z0zero(x[i], NombreEnLettres);
    if (NombreEnLettres != NULL)
        printf("%s.\n", NombreEnLettres);

    }

    return EXIT_SUCCESS;
}

zero.
un.
deux.
trois.
quatre.
cinq.
sept.
huit.
neuf.
dix.
onze.
douze.
treize.
quatorze.
quinze.
seize.
dix-sept.
dix-huit.
dix-neuf.
vingt.
vingt et un.
vingt-neuf.
trente.
quarante.
quarante-deux.
cinquante et un.
soixante.
soixante-neuf.
soixante-dix.
soixante et onze.
soixante-dix-sept.
quatre-vingts.
quatre-vingt-un.
quatre-vingt-cinq.
quatre-vingt-dix.
quatre-vingt-onze.
quatre-vingt-dix-neuf.
cent.
cent un.
cent dix.
cent trente.
cent soixante-treize.
cent quatre-vingt-seize.
deux cents.
deux cent cinq.
deux cent dix-sept.
deux cent vingt-trois.
deux cent cinquante-six.
deux cent soixante-huit.
deux cent soixante-treize.
deux cent quatre-vingts.
deux cent quatre-vingt-dix-sept.
sept cent trente-quatre.
mille.
mille un.
mille dix-sept.
mille vingt.
mille trente-deux.
mille cent onze.
deux mille.
deux mille cent.
deux mille deux cents.
trois mille trois.
trois mille sept cent quatre-vingts.
dix mille.
dix mille cinq.
dix mille neuf cents.
onze mille.
onze mille sept cents.
douze mille.
dix-huit mille huit cent cinq.
soixantemille quatre cents.
soixante-dix-sept mille dix.
quatre-vingt mille.
quatre-vingt mille soixante-dix-huit.
quatre-vingt-dix mille.
quatre-vingt-douze mille deux.
quatre-vingt-dix-sept mille quatre cent cinquante-neuf.
cent mille.
cent mille sept.
deux cent quatre mille trois.
trois cent dix mille huit cent cinquante-sept.
sept cent mille cinq.
un millions.
deux millions.
deux millions mille un.
soixante-douze millions quatre cent vingt-quatre mille six cents.
quatre-vingts millions.
soixante-dix-neuf millions huit cent vingt-huit mille quatre cent quatre-vingts.
deux cents millions.
sept cent huit millions.
un milliard.
deux milliards.
deux milliards cinq cent mille.
deux milliards sept cent quatre-vingt mille un.
cent onze milliards cent onze millions cent onze mille cent onze.
neuf cent quatre-vingt-dix milliards neuf cent quatre-vingt-dix millions neuf cent quatre-vingt-dix mille neuf cent quatre-vingt-dix.
candide@candide-desktop:~$
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 18:11:45

Justement, le truc très ... étrange c'est que quand j'utilise ta liste j'obtiens 1000000 -> un millions mais si je le demande à l'utilisateur, j'obtiens 1000000 -> un million.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 18:15:49

Citation : Lithrein

mais si je le demande à l'utilisateur,



Oui mais ça pour ça que je dis qu'il ne faut pas confondre la cerise et le gâteau : avant de s'occuper de la gestion des données de l'utilisateur, on s'assure que le code fonctionne en soi, autrement dit, avant de poser la cerise, on fait un bon gâteau.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 18:32:31

Je viens de comprendre pourquoi, les code de Lithrein segfault avec le test de candide et pas avec le mien...
int main(void)
{
    unsigned long long i;
    for(i = 0; i <= 999999999; ++i)
    {
        char s[13];
        char res1[MAX_LEN] = {0};
        char res2[MAX_LEN] = {0};
        sprintf(s, "%llu", i);
        z0zero(s, res1);
        z0zero2(s, res2);

        if(strcmp(res1, res2))
        {
            printf("diff : %s %s -> %s\n", s, res1, res2);
            break;
        }
    }

    return 0;
}

Les chaînes à tester chez candide ne sont pas modifiables, les miennes, si... Donc je n'avais pas vu que la chaîne source était modifiée dans la fonction.

Par contre pour le coup de l'entrée à 1000000, j'ai la bonne réponse, avec les 2 tests. o_O
Pour tester, avec les entrées de candide, j'ai du bidouiller un peu la fonction de Lithrein(strcpy), pour ne pas modifier l'entrée.
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
10 janvier 2010 à 18:37:45

En fait tu fais de jolis dépassements :-°
Regarde ta condition :

if (index > 0 && srcLen > 3 && (src[i-1] != '0' || src[i-2] != '0' || src[i-3] != '0'))


Quand i=0 tu passes quand même dans ta condition et du coup src[-1] je connais pas moi :p
Si tu testes avec 001000000 tu verras que ton problème disparaît ;)

Tu peux simplifier ça je pense aussi :

/* 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 */
}

Et pour que ça soit plus lisible tu pourrais étaler sur plusieurs lignes parce que scroller juste pour une fonction c'est pas terrible :D

sprintf(buf, "%s%s%s ", (i != 0 && src[i-1] != '0' &&
						 (val != 1 || (1 == val && (src[i-1]-'0' == 8 || src[i-1]-'0' == 9))))?"-":"",
		(i != 0 && 1 == val && src[i-1] != '0' && src[i-1]-'0' != 8 && src[i-1]-'0' != 9)?" et ":"",
		(i != 0 && (7 == src[i-1]-'0' || 9 == src[i-1]-'0') && val < 7)? unites_irr[val-1] : unites[val]);
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 18:51:24

Citation : Pouet_forever

En fait tu fais de jolis dépassements :-°
Regarde ta condition :

if (index > 0 && srcLen > 3 && (src[i-1] != '0' || src[i-2] != '0' || src[i-3] != '0'))



Quand i=0 tu passes quand même dans ta condition et du coup src[-1] je connais pas moi :p
Si tu testes avec 001000000 tu verras que ton problème disparaît ;)



Euh, non, il ne me semble pas qu'il y a dépassement car si index > 0 (index me sers à savoir si je dois afficher mille, millions, ...) donc i est toujours supérieur à trois si la première condition est respecté or pour évaluer la condition il vérifie que index est supérieur 0, si c'est vrai il continue d'évaluer les conditions suivantes sinon il saute le blocs d'instructions if sans rien évaluer d'autre.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 19:08:30

Bah il semblerai que si :p
GDB me le confirme :

(gdb) p index
$1 = 2
(gdb) p i
$2 = 1
(gdb) p srcLen
$3 = 7 '\a'
(gdb) x/s src+i-1
0x100001c7f:         "1000000"


1-3 = -2 :p

Edit : Oups j'ai oublié la valeur importante ^^
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 19:23:26

Citation : Pouet_forever

Bah il semblerai que si :p
GDB me le confirme :

(gdb) p index
$1 = 2



2-3 = -1 :p


Il semblerais que non, sinon valgind me dirai que je lis là où il faut pas.
Or,
valgrind ./x
==12322== Memcheck, a memory error detector.
==12322== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==12322== Using LibVEX rev 1884, a library for dynamic binary translation.
==12322== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==12322== Using valgrind-3.4.1-Debian, a dynamic binary instrumentation framework.
==12322== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==12322== For more details, rerun with: -v
==12322==
max : 999 999 999 999 999 999 999 999
exemples: 1 000 000, 1000000
Saisissez votre nombre :
1000000
un million.
==12322==
==12322== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==12322== malloc/free: in use at exit: 0 bytes in 0 blocks.
==12322== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==12322== For counts of detected errors, rerun with: -v
==12322== All heap blocks were freed -- no leaks are possible.


Ps: Plus vite j'aurais fait un correctif plus viable et plus maintenable, mieux ce sera.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 19:38:23

As u wish !
Toujours est-il que GDB ne ment pas :p
J'ai fait un breakpoint juste après ta condition (sur la déclaration de 'buf') et à chaque fois que je mets un nombre de longueur différente d'un multiple de 3 (pas que pour 1000000) i est inférieur à 3. Donc i-3<0.
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 19:42:57

Dommage qu'on ne précise pas les notions a connaitre pour faire tel exercice
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 20:13:23

Citation : Pouet_forever

As u wish !
Toujours est-il que GDB ne ment pas :p
J'ai fait un breakpoint juste après ta condition (sur la déclaration de 'buf') et à chaque fois que je mets un nombre de longueur différente d'un multiple de 3 (pas que pour 1000000) i est inférieur à 3. Donc i-3<0.



Prenons par exemple le nombre 1 000 000.
On est d'accord sur le fait que:
i = 1
index = 2
srcLen = 7

Si on évalue la condition :
if (index > 0 && srcLen > 3 && (src[i-1] != '0' || src[i-2] != '0' || src[i-3] != '0'))

, on en arrive à un truc du style :
index strictement supérieur à 0,
donc on évalue la condition suivante,
srcLen strictement supérieur à 3,
donc on évalue la condition suivante,
src[i-1] est égale à 0,
on assimile donc (src[i-1] != '0' || src[i-2] != '0' || src[i-3] != '0') à 0
ainsi on obtient if (1 && 1 && 0) <=> if (0).

Si garantie qu'il n'y a pas d'erreur, non ?
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2010 à 20:26:55

C'est là que tu as faux :

Citation : Lithrein

src[i-1] est égale à 0,



src[i-1] == '1' et pas '0'
Du coup c'est après que ça va pas : (src[i-1]-'0'>1 || src[i-2]-'0'>0 || src[i-3]-'0'>0)
Comme <minicode type="c">src[i-1]-'0'>1</minicde> sera faux (1 n'est pas supérieur à 1) et donc tu évalueras le reste qui n'appartient pas à ton tableau :)

@zoom751 : Pour faire cet exercice il faut que tu connaisses bien la notion de chaîne de caractères et caractères (et pointeurs naturellement). Le reste est abordable si tu réfléchis un peu ;)
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
10 janvier 2010 à 20:27:37

J'ai beau essayer de comprendre vos codes...J'y arrive pas XD
  • Partager sur Facebook
  • Partager sur Twitter