Commentçamarche.net
CodeS-SourceS
Rechercher un code, un tuto, une réponse

Interpreteur de calcul intégré à la saisie au clavier

0/5 (2 avis)

Snippet vu 6 420 fois - Téléchargée 16 fois

Contenu du snippet

Cette fonction n'est pas une calculatrice en soi, elle se contente d'interpréter un calcul dans le cadre d'une saisie de valeur numérique par l'utilisateur

Source / Exemple :


#define NA 12345678 /*Valeur d'erreur renvoyée pour les calculs*/
#define defo 1111111 /*Valeur indiquant une saisi par défaut pour les calculs*/

float interpret_calc()
{
    char *chaine, *signes;
    float *nombres;
    int i,j,k,b1=0,b2=0,b3,nbparo=0,nbparf=0,nbmuldiv=0,nbt=0,index=0;
    int *indexparo, *indexparf, *indexmuldiv;
    float temp,nb1,nb2;
    chaine = chaine_din();    /*Saisi le calcul*/
    if (strstr(chaine,"q") != NULL || strstr(chaine,"Q") != NULL)
    {    /*Quitte si q*/
        free(chaine);
        exit(0);
    }
    i = strlen(chaine);    /*i = taille complète du calcul*/
    if (!i)    /*Si la chaine est vide, renvoi une erreur*/
        return (defo);
    ER = nombres = calloc(i,sizeof(float));
    Erreur(1);
    ER = signes = calloc(i,sizeof(char));
    Erreur(1);
    ER = indexparo = calloc((int)i/2,sizeof(int));
    Erreur(1);
    ER = indexparf = calloc((int)i/2,sizeof(int));
    Erreur(1);
    ER = indexmuldiv = calloc((int)i/2,sizeof(int));
    Erreur(1);
    for (i=0;i<strlen(chaine);i++)
    {    /*Change , en .*/
        if (chaine[i] == ',')
            chaine[i] = '.';
    }
    while (strlen(chaine))
    {
        if (isdigit(chaine[0]) > 0)
        {        /*Si le premier caractère est un chiffre*/
            b1=1;        /*indique nombres*/
            nombres[index] = atof(chaine);    /*Saisi valeur et stocke dans le tableau 1*/
            if (b2==1)            /*Valeur négative*/
                nombres[index]*=-1;
            b2=0;
            signes[index++] = '0';      /*Met 0 dans le tableau 2*/
            nbt++;
            while (isdigit(chaine[0]) || chaine[0] == '.')
            {            /*retire la valeur saisie de la string*/
                for (i=0;i<strlen(chaine);i++)
                    chaine[i] = chaine[i+1];
            }
        }
        else
        {        /*Donc si signe de calcul*/
            if (chaine[0] == '-' && b1 == 0)
            {            /*Si un - se trouve apres un autre signe*/
                b2=1;            /*Nombre négatif*/
                nombres[index] = 0;     /*Place 0 et # dans les tableaux*/
                signes[index++] = '#';
                nbt++;
            }
            else
            {    /*Si c'est pas un nb négatif*/
                b1=0;      /*Indique signe*/
                signes[index] = chaine[0];   /*Place 0 dans le tableau 1 et le signe dans le tableau 2*/
                nombres[index++] = 0;
                nbt++;
                switch (signes[index-1])
                {        /*reperage du signe utilisé*/
                    case '*':
                    case '/':
                        indexmuldiv[nbmuldiv] = index-1;
                        nbmuldiv+=1;
                        break;
                    case '(':
                        indexparo[nbparo] = index-1;
                        nbparo+=1;
                        break;
                    case ')':
                        indexparf[nbparf] = index-1;
                        nbparf+=1;
                        break;
                    case '+':
                    case '-':
                        break;
                    default:   /*Si aucun signe n'est reconnu*/
                        printf("Erreur: le symbole %c n'est pas reconnu", signes[index-1]);
                        free(nombres);free(signes);free(indexparo);free(indexparf);free(indexmuldiv);free(chaine);
                        Pause();
                        return NA;
                }
            }
            for (i=0;i<strlen(chaine);i++)
                chaine[i] = chaine[i+1]; /*Retire le signe de la string*/
        }
    }
    if (nbparo != nbparf)
    {    /*Si ya pa autant de parenthèses ouvrantes et fermantes*/
        printf("Erreur: %d parenth%cses ouvertes, %d parenth%cses fermees", nbparo, accchar('è') ,nbparf, accchar('è'));
        free(nombres);free(signes);free(indexparo);free(indexparf);free(indexmuldiv);free(chaine);
        Pause();
        return NA;
    }
    do
    {
        if (nbparo) /*Si ya des parentheses*/
        {
            b2 = indexparf[0];     /*borne 2 à la 1ere parenthèse fermante*/
            for (i=0;i<nbparo;i++)
            {
                if (indexparo[i] < b2)  /*Si la parenthese ouvrante est avant la fermante*/
                    b1 = indexparo[i];  /*borne 1 à la parenthese*/
            }                    /*Donc les 2 bornes se resserrent sur les plus profondes parenthèses*/
            signes[b1] = '#';   /*Place des # à la place des parenthèses utilisées*/
            signes[b2] = '#';
            nbparo--;
            for (i=b1;i<nbparo;i++)     /*Supprime les index des parenthèses utilisées*/
                indexparo[i] = indexparo[i+1];
            for (i=0;i<nbparo;i++)
                indexparf[i] = indexparf[i+1];
        }
        else
        {        /*Si ya pas de parenthèses, ou plus de parenthèses*/
            b1 = -1;     /*Bornes à -1 et max*/
            b2 = nbt;
        }
        for (i=0;i<nbmuldiv;i++)
        {        /*Boucle sur le nombre de signes * ou / */
            if (indexmuldiv[i] > b1 && indexmuldiv[i] < b2)
            {            /*Si le signe se trouve entre les 2 bornes*/
                b3 = indexmuldiv[i];    /*Borne 3 à l'emplacement du signe*/
                indexmuldiv[i] = -1;    /*index du signes à -1*/
            }
            else
                b3 = -1;  /*sinon borne 3 à -1*/
            if (b3 != -1)
            {    /*Si la borne 3 est utilisée*/
                for(j=b3-1;j>b1;j--)
                {       /*Saisi valeur 1*/
                    if (nombres[j] || (!nombres[j] && signes[j] == '0'))
                    {      /*Si le nombre est différent de 0 ou qu'il est égal à 0 et que le tab 2 contient aussi 0*/
                        nb1 = nombres[j];
                        signes[j] = '#';   /*Place 0 et # dans les tableaux*/
                        nombres[j] = 0;
                        break;
                    }
                }
                for(k=b3+1;k<b2;k++)
                {       /*Saisi valeur 2... idem*/
                    if (nombres[k] || (!nombres[k] && signes[k] == '0'))
                    {
                        nb2 = nombres[k];
                        signes[k] = '#';
                        nombres[k] = 0;
                        break;
                    }
                }
                if (k==b2)
                {   /*Si aucune valeur n'est trouvée pour nb2*/
                    nombres[j] = nb1;   /*Replace nb1 dans le tableau 1, puis met 0 dans le tableau 2*/
                    signes[j] = '0';
                }
                if (signes[b3] == '*')
                    temp = nb1*nb2;      /*Multiplication*/
                if (signes[b3] == '/')
                {
                    if (nb2 == 0)
                    {
                        puts("Erreur: Division par 0 !!!");
                        free(nombres);free(signes);free(indexparo);free(indexparf);free(indexmuldiv);free(chaine);
                        Pause();
                        return NA;
                    }
                    temp = nb1/nb2;     /*Division*/
                }
                signes[b3] = '0';    /*Met 0 dans le tableau 2*/
                nombres[b3] = temp;  /*Place le résultat du calcul dans le tableau 1*/
            }
        }
        for(i=b1+1;i<b2;i++)
        {
            for(j=b1+1;j<b2;j++)
            {         /*Saisi valeur 1*/
                if (nombres[j] != 0 || (!nombres[j] && signes[j] == '0'))
                {
                    nb1 = nombres[j];
                    signes[j] = '#';
                    nombres[j] = 0;
                    break;
                }
            }
            for(k=b1+1;k<b2;k++)
            {        /*Saisi valeur 2*/
                if (nombres[k] || (!nombres[k] && signes[k] == '0'))
                {
                    nb2 = nombres[k];
                    signes[k] = '#';
                    nombres[k] = 0;
                    break;
                }
            }
            if (k==b2)
            {
                nombres[j] = nb1;
                signes[j] = '0';
            }
            for(j=b1+1;j<b2;j++)
            {
                switch (signes[j])
                {
                    case '+':
                        temp = nb1+nb2;     /*Addition*/
                        break;
                    case '-':
                        temp = nb1-nb2;     /*Soustraction*/
                        break;
                }
                if (signes[j] == '+' || signes[j] == '-')
                {      /*Si addition ou soustraction*/
                    signes[j] = '0';     /*Met 0 dans le tableau 2*/
                    nombres[j] = temp;   /*Et le resultat du calcul dans le tableau 1*/
                    break;
                }
            }
        }
    } while (b1 != -1 || b2 != nbt); /*Fin du calcul si les bornes sont maximum*/
    i=0;
    do
    {
        temp = nombres[i];    /*Prend comme résultat la seule valeur restant dans le tableau*/
    } while (!temp && ++i<nbt);
    free(nombres);free(signes);free(indexparo);free(indexparf);free(indexmuldiv);free(chaine);
    return temp; /*Renvoi le résultat du calcul*/
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.