Partage
  • Partager sur Facebook
  • Partager sur Twitter

zCalc

Du 1er au 30 Septembre

    2 septembre 2010 à 18:56:07

    Ok ! :D
    Je vais rajouter les fonctions à mon code aussi. :)
    • Partager sur Facebook
    • Partager sur Twitter
      2 septembre 2010 à 19:18:02

      Citation : Pouet_forever

      @ Holt : Ca marche, pas réussi à mettre ton code en défaut. :)


      En fait je pense que pour le "peu" que j'ai implémenté, il devrait passer. Par contre sous la forme où il est ça va être très dur de rajouter des choses (du style cos, etc... ). C'est pour ça que je vais le ré-organiser avant de continuer à ajouter des fonctions ;)
      • Partager sur Facebook
      • Partager sur Twitter
        2 septembre 2010 à 19:45:20

        Voilà, mon code gère normalement les espaces.

        Et j'ai découvert une fonctionnalité sympa, sans que je fasse exprès de la coder pour déclarer plusieurs variables à la fois :

        >>>a = b = c = d = 100
        100
        >>>vars
        d = 100
        c = 100
        b = 100
        a = 100
        • Partager sur Facebook
        • Partager sur Twitter
          2 septembre 2010 à 23:30:47

          J'ai fait les fonctions a 1 ou plusieurs arguments, le seul hic c'est que c'est chiant avec les fonctions de callback... bah oui faut que les fonctions aient toutes le même prototype... :-°

          #include <stdio.h>
          #include <stdlib.h>
          #include <ctype.h>
          #include <string.h>
          #include <math.h>
          
          #define N_MAX 1000
          
          enum { VIDE, NUMER, OPER };
          
          typedef struct stack_s {
            int st[N_MAX][2];
            int i_st;
          } stack;
          
          typedef struct n_stack_s {
            stack st[2];
          } n_stack;
          
          typedef struct variables_s {
            char nom[50];
            int len_nom;
            int val;
            struct variables_s * suiv;
          } variables;
          
          typedef struct fonctions_s {
            int args[10];
            int nb_args;
          } fonctions;
          
          #pragma mark Globales
          variables vars;
          
          #pragma mark Prototypes
          /* >>>>>>>>>>>>>>>>>>>> Prototypes <<<<<<<<<<<<<<<<<<<< */
          int convert_npi(n_stack * st, char * s);
          int calcul_npi(stack * s);
          
          #pragma mark Fonctions
          
          void supp_espaces(char ** s) {
            while (isspace(**s))
              (*s)++;
          }
          
          variables * creer_var(char * nom, int val) {
            variables * tmp = malloc(sizeof *tmp);
            
            if (tmp == NULL) {
              fprintf(stderr, "Erreur d'allocation: %s\n", nom);
              return NULL;
            }
            strcpy(tmp->nom, nom);
            tmp->val = val;
            tmp->len_nom = strlen(nom);
            tmp->suiv = NULL;
            
            return tmp;
          }
          
          void set_var(char * nom, int val) {
            int exists = 0;
            variables * v = &vars;
            
            /* Regarde si la variable existe */
            variables * tmp = v->suiv;
            while (1) {
              if (strcmp(v->nom, nom) == 0) {
                exists = 1;
                break;
              }
              if (tmp == NULL)
                break;
              v = tmp;
              tmp = tmp->suiv;
            }
            
            if (exists) {
              v->val = val;
            }
            else {
              /* Si elle n'existe pas, on la crée */
              if (!v)
                v = creer_var(nom, val);
              else
                v->suiv = creer_var(nom, val);
            }
          }
          
          int isoper(int n) {
            char oper[] = { '+', '-', '*', '/', '(', ')' };
            int sz = sizeof oper / sizeof *oper;
            int i;
            
            for (i = 0; i < sz; i++)
              if (n == oper[i])
                return 1;
            return 0;
          }
          
          int set_prio(int op) {
            int i, sz;
            struct {
              char op;
              int val;
            } equ[] = {
              { '(', 0 },
              { '+', 1 },
              { '-', 2 },
              { '*', 3 },
              { '/', 4 }
            };
            
            sz = sizeof equ / sizeof *equ;
            for (i = 0; i < sz; i++)
              if (op == equ[i].op)
                return equ[i].val;
            
            /* Opérateur pas dans la liste */
            return 0;
          }
          
          /* Retourne la priorité de op1 par rapport à op2 */
          /* '(' < '+' < '-' < '*' < '/' */
          int priorite(int op1, int op2) {
            op1 = set_prio(op1);
            op2 = set_prio(op2);
            return op1 > op2;
          }
          
          void push(stack * s, int n, int type) {
            s->st[s->i_st][0] = n;
            s->st[s->i_st][1] = type;
            s->i_st++;
          }
          
          int pop(stack * s) {
            int tmp = s->st[s->i_st-1][0];
            s->st[s->i_st-1][0] = VIDE;
            s->st[s->i_st-1][1] = VIDE;
            s->i_st--;
            return tmp;
          }
          
          /* Recupere le nom de la variable */
          void recup_nom(char * (*s), char * nom) {
            int i;
            
            i = 0;
            while (isalpha(**s)) {
              nom[i] = **s;
              (*s)++;
              i++;
            }
            nom[i] = '\0';
          }
          
          int apply_var(n_stack * st, char * (*s), char * nom) {
            int i;
            int exists = 0;
            variables * v = &vars;
            
            /* Regarde si la variable existe */
            /* i sert pour la position dans la liste chaînée */
            i = 1;
            while (v != NULL) {
              if (strncmp(v->nom, nom, v->len_nom) == 0) {
                exists = 1;
                break;
              }
              i++;
              v = v->suiv;
            }
            
            supp_espaces(s);
            
            /* On vérifie si il s'agit d'une affectation */
            if (**s == '=') {
              /* Crée la variable si elle n'existe pas */
              if (!exists)
                set_var(nom, 0);
              (*s)++;
              return i;
            }
            
            if (exists) {
              push(&st->st[0], v->val, NUMER);
            }
            else {
              fputs("Variable inexistante.", stderr);
              return -1;
            }
            return 0;
          }
          
          int recup_arg(n_stack * st, char * (*s), int delim) {
            char tmp_s[N_MAX] = "";
            int j, par;
            
            if (delim != ')')
              (*s)++;
            
            par = j = 0;
            do {
              if (**s == '(')
                par++;
              else if (**s == ')')
                par--;
              tmp_s[j] = **s;
              j++;
              (*s)++;
              /* Pour les parentheses si on a plusieurs parentheses dans l'exp */
            } while (**s && ((**s != delim && delim != ')') || par > 0));
            tmp_s[j] = '\0';
            
            /*if (**s != delim) {
              fprintf(stderr, "Utilisation de la fonction.\n");
              return -1;
            }
            else */{
              int affect;
              
              if (delim != ')' && **s == delim)
                (*s)++;
              
              affect = convert_npi(st, tmp_s);
              if (affect < 0) {
                fprintf(stderr, "Parametre de la fonction.\n");
                return -1;
              }
            }
            return 0;
          }
          
          int calc_arg(int * affect, char * (*s), int delim) {
            n_stack tmp_st;
            
            memset(&tmp_st, 0, sizeof tmp_st);
            *affect = recup_arg(&tmp_st, s, delim);
            if (*affect < 0)
              return -1;
            else
              return calcul_npi(&tmp_st.st[0]);
          }
          
          int fct_1arg(n_stack * st, char * (*s), double (*f) (double)) {
            supp_espaces(s);
            
            if (**s != '(') {
              fprintf(stderr, "Utilisation de la fonction.\n");
              return -1;
            }
            else {
              int n, affect;
              
              n = calc_arg(&affect, s, ')');
              if (affect < 0)
                return -1;
              
              n = f(n);
              push(&st->st[0], n, NUMER);
            }
            return 0; 
          }
          
          int fct_2arg(n_stack * st, char * (*s), double (*f) (double,double)) {
            supp_espaces(s);
            
            if (**s != '(') {
              fprintf(stderr, "Utilisation de la fonction.\n");
              return -1;
            }
            else {
              int n1, n2, affect;
              
              n1 = calc_arg(&affect, s, ',');
              if (affect < 0)
                return -1;
              n2 = calc_arg(&affect, s, ')');
              if (affect < 0)
                return -1;
              
              n1 = f(n1, n2);
              push(&st->st[0], n1, NUMER);
            }
            return 0;
          }
          
          int apply_fct(n_stack * st, char * (*s), char * nom) {
            struct {
              char * nom;
              int (*callback) (n_stack *, char **, double (*) (double));
              double (*f) (double);
            }
            fcts[] = {
              { "sqrt"    , fct_1arg    , sqrt  },
              { "abs"     , fct_1arg    , fabs  }
              /*{ "hypot"   , fct_2arg   , hypot }*/
            };
            
            int sz_fcts = sizeof fcts / sizeof *fcts;
            int i;
            
            for (i = 0; i < sz_fcts; i++)
              if (strcmp(fcts[i].nom, nom) == 0)
                return fcts[i].callback(st, s, fcts[i].f);
            
            return 1;
          }
          
          /* Retourne l'indice de la variable dans la liste chaînée */
          /* -1 -> Erreur
           *  0 -> Existe
           * >0 -> N'existe pas */
          int var_ou_fct(n_stack * st, char * (*s)) {
            int p;
            char nom[50] = "";
            
            recup_nom(s, nom);
            p = apply_fct(st, s, nom);
            if (p > 0)
              return apply_var(st, s, nom);
            else
              return p;
          }
          
          void supp_elem_var(int ind) {
            int i;
            variables * v = &vars;
            variables * tmp_prev;
            variables * tmp_nxt;
            
            for (i = 1; i < ind; i++)
              v = v->suiv;
            
            tmp_prev = v;
            tmp_nxt = v->suiv->suiv;
            free(v);
            tmp_prev->suiv = tmp_nxt;
          }
          
          char * set_elem_var(int ind, int val) {
            int i;
            variables * v = &vars;
            
            for (i = 1; i < ind; i++)
              v = v->suiv;
            
            set_var(v->nom, val);
            return v->nom;
          }
          
          /* La stack 1 sert pour la NPI, la stack 2 pour les opérateurs */
          /* Une fois la fonction finie, seule la stack 1 est remplie */
          
          /* Retourne l'indice de la variable dans la liste chaînée */
          /* -1 -> Erreur
           *  0 -> Fonction 'normale' de calcul
           * >0 -> Position dans la liste chaînée */
          int convert_npi(n_stack * st, char * s) {
            int prem = 1;
            int var_trouve = -1;
            
            while (*s) {
              /* On vide les blancs */
              supp_espaces(&s);
              
              /* Si c'est une variable */
              if (isalpha(*s)) {
                int tmp = var_ou_fct(st, &s);
                /* Variable créée si elle n'existe pas, la supprimer si
                 * l'affectation n'est pas bonne */
                if (tmp > 0 && prem)
                  var_trouve = tmp;
                else if (tmp > 0 && !prem) {
                  fputs("Erreur d'affectation.", stderr);
                  /* Supprime la variable créée précédement */
                  supp_elem_var(tmp);
                  return -1;
                }
                //else if (tmp < 0)
                  //fputs("Variable inexistante.", stderr);
              }
              /* Si c'est un nombre */
              else if (isdigit(*s)) {
                push(&st->st[0], strtol(s, &s, 10), NUMER);
              }
              /* Si c'est un opérateur */
              else if (isoper(*s)) {
                /* On ajoute sur la stack 2 si elle est vide ou si on a
                 * une parenthèse */
                if (st->st[1].i_st == 0 || *s == '(') {
                  push(&st->st[1], *s, OPER);
                }
                /* Sinon, on regarde si c'est un parenthèse fermante */
                else if (*s == ')') {
                  /* Si c'est le cas, on dépop toute la stack 2
                   * jusqu'à la parenthèse */
                  while (st->st[1].st[st->st[1].i_st-1][0] != '(') {
                    int tmp = pop(&st->st[1]);
                    push(&st->st[0], tmp, OPER);
                  }
                  pop(&st->st[1]);
                }
                /* Sinon on regarde la priorité des opérateurs.
                 * Si l'opérateur en cours a une prio plus importante, on le stocke,
                 * sinon on depop sur la stack 1 */
                else {
                  if (priorite(*s, st->st[1].st[st->st[1].i_st-1][0]) == 1) {
                    push(&st->st[1], *s, OPER);
                  }
                  else {
                    /* Tant que la prio de l'op en cours est inférieure à celle
                     * sur la stack, on dépile sur la stack 1 */
                    while (priorite(*s, st->st[1].st[st->st[1].i_st-1][0]) != 1) {
                      int tmp = pop(&st->st[1]);
                      push(&st->st[0], tmp, OPER);
                    }
                    /* On mets l'op sur la stack 2 */
                    push(&st->st[1], *s, OPER);
                  }
                }
                /* On passe l'opérateur */
                s++;
              }
              /* Ce n'est plus le premier tour de boucle */
              prem = 0;
            }
            
            /* Une fois que la chaîne est vide,
             * il faut vider la stack 2 sur la stack 1 */
            while (st->st[1].i_st != 0) {
              int tmp = pop(&st->st[1]);
              push(&st->st[0], tmp, OPER);
            }
            
            return var_trouve < 0 ? 0 : var_trouve;
          }
          
          int calcul_npi(stack * s) {
            int n1, n2, op;
            
            if (s->i_st == 0)
              return s->st[0][0];
            if (s->st[s->i_st-1][1] == NUMER)
              return pop(s);
            if (s->st[s->i_st-1][1] == OPER &&
                (s->st[s->i_st-1][0] == '(' ||
                 s->st[s->i_st-1][0] == ')')) {
              pop(s);
              return calcul_npi(s);
            }
            
            op = s->st[s->i_st-1][0];
            pop(s);
            n1 = calcul_npi(s);
            n2 = calcul_npi(s);
            
            if (op == '+')
              return n2 + n1;
            else if (op == '-')
              return n2 - n1;
            else if (op == '*')
              return n2 * n1;
            else if (op == '/') {
              if (n1 == 0) {
                fputs("Division par 0, remplacée par 1.", stderr);
                n1 = 1;
              }
              return n2 / n1;
            }
            
            return 0;
          }
          
          void virer_entree(char * s) {
            char * c = strchr(s, '\n');
            
            if (c)
              *c = '\0';
          }
          
          void prompt(void) {
            int done = 0;
            char s[N_MAX] = "";
            int affect;
            int calc;
            n_stack st;
            
            while (!done) {
              memset(&st, 0, sizeof st);
              
              printf(">>> ");
              fgets(s, N_MAX, stdin);
              virer_entree(s);
              
              if (strcmp(s, "quit") == 0 || *s == 'q')
                return;
              else if (*s == 'c')
                set_var("ans", 0);
              else {
                affect = convert_npi(&st, s);
                
                if (affect >= 0)
                  calc = calcul_npi(&st.st[0]);
                
                if (affect > 0)
                  printf("%s = ", set_elem_var(affect, calc));
                printf("%d\n", calc);
                set_var("ans", calc);
              }
            }
          }
          
          int main(void) {
            strcpy(vars.nom, "ans");
            vars.len_nom = 3;
            vars.val = 0;
            vars.suiv = NULL;
            
            prompt();
            return EXIT_SUCCESS;
          }
          

          Là je n'ai 'activé' que les fonctions à 1 argument, ya abs et sqrt. Je verrai plus tard pour perfectionner le truc et jouer avec le préprocesseur (génération auto de fonctions). :)
          • Partager sur Facebook
          • Partager sur Twitter
            2 septembre 2010 à 23:41:07

            J'ai codé une solution basique par descente récursive. Les analyses lexicale, syntaxique et l'évaluation sont confondues, c'est la seule originalité, et ça rend peut-être le code pas très clair.

            Le code se contente du strict minimum : les quatre opérations élémentaires, les parenthèses et ne gère que la saisie d'entiers positifs (il faut aussi dire que je n'utilise pas scanf ou une autre fonction standard complexe fournissant un travail de parsage).


            Désolé, il n'y a pas de commentaires et c'est pas vraiment aéré.
            #include <stdio.h>#include <stdio.h>
            #include <stdlib.h>
            #include <setjmp.h>
            
            float ligne(void);
            float expr(void);
            float finexpr(float);
            float terme(void);
            float finterme(float);
            float facteur(void);
            
            enum {ExpErr = -1, Ok, Clear, Quit, ZeroDivision};
            jmp_buf endroit;
            float ans = 0;
            
            float ligne(void){
            	char c;
            	float res;
            	while (( c = getchar() ) == ' ');
            	if (c == 'c' || c == 'q'){
            		if (getchar()=='\n')
            			longjmp(endroit, c == 'c' ? Clear : Quit);
            		longjmp(endroit,ExpErr);}	
            	ungetc(c,stdin);	
            	res = expr();
            	if (getchar()=='\n') return res;
            	longjmp(endroit,ExpErr);}
            
            float expr(void){
            	return finexpr(terme());}
            	
            float finexpr(float res){
            	char c;
            	while (( c = getchar() ) == ' ');	
            	if (c=='+')
            		return finexpr(res + terme());
            	else if (c=='-')
            		return finexpr(res - terme());
            	else ungetc(c,stdin);
            	return res;}
            
            float terme(void){	
            	return finterme(facteur());}
            
            float finterme(float res){
            	char c;
            	while (( c = getchar() ) == ' ');
            	if (c=='*')
            		return finterme(res * facteur());
            	else if (c=='/'){
            		float diviseur = facteur();
            		if (diviseur == 0) longjmp(endroit,ZeroDivision);
            		return finterme(res / diviseur);}
            	else ungetc(c,stdin);	
            	return res;}
            	
            float facteur(void){
            	char c;
            	int i;
            	float res = 0;
            	while (( c = getchar() ) == ' ');
            	if (c>='0' && c<='9'){		
            		do { res = 10 * res + c - '0';
            			 c = getchar();}
            		while(c>='0' && c<='9');
            		ungetc(c,stdin);}
            	else if (c =='('){		
            		res = expr();
            		while (( c = getchar() ) == ' ');
            		if (c != ')') longjmp(endroit, ExpErr);}
            	else {
            		ungetc(c,stdin);
            		for(i=0; i<3; i++)
            			if (getchar()!="ans"[i]) longjmp(endroit, ExpErr);
            		res = ans;}	
            	return res;}
            	
            int main(void){	
            	while (1){
            	 printf(">> ");
            	 switch(setjmp(endroit)){
            		case Ok:
            			ans = ligne();
            			printf("%.2f\n",ans);
            			break;
            		case Clear:
            			ans =0; break;
            		case Quit:
            			puts("\nFin."); return 0;
            		case ExpErr:
            			puts("\nExpression invalide");
            			while(getchar()!='\n'); break;
            		case ZeroDivision:
            			puts("\nErreur : Division par zéro");
            			while(getchar()!='\n');}
            		}
            	}
            
            • Partager sur Facebook
            • Partager sur Twitter
              3 septembre 2010 à 9:36:20

              @PouetForever :

              >>> a = b = 15
              Erreur d'affectation.Erreur de segmentation

              >>> sqrt(-10)
              -2147483648
              >>> sqrt 25
              Utilisation de la fonction.
              25
              >>>


              Sinon, lorsque l'on rentre une bonne entrée, ça à l'air bon :) .
              • Partager sur Facebook
              • Partager sur Twitter
                3 septembre 2010 à 10:59:06

                J'ai pas géré les affectations multiples, et comme dit à chaque fois je considère que l'utilisateur est intelligent. ^^
                • Partager sur Facebook
                • Partager sur Twitter
                  3 septembre 2010 à 19:41:49

                  Bonjour,

                  C'est pas de bol, je suis déjà confronté à un problème alors que je ne suis qu'à la fonction débutant... Mon problème est simple : dès que je fais une des opérations (+, -, * ou /), mon code conserve le \n de la fin. Ce qui donne :
                  Entrez un nombre : 5
                  Quelle opération (+, -, *, /) ? 5 +
                  Merci de choisir une opération valide
                  Quelle opération (+, -, *, /) ? 5 +
                  Entrez un nombre : 6
                  Quelle opération (+, -, *, /) ? 11


                  quelqu'un peut me dire comment supprimer ça ? J'utilise pourtant la fonction du jeu du pendu :p
                  D'avance merci.

                  char lireCaractere()
                  {
                      char caractere = 0;
                  
                      caractere = getchar();
                      while (getchar() != '\n') ; //ça ne supprime pas le \n ça ???
                  
                      return caractere;
                  }
                  
                  lancerCalculetteV1()
                  {
                      int b_continuer = 1;
                      int nombre = 0;
                      int resultat = 0;
                      char operation;
                  
                      printf("** ZCalc (niveau 1) **\n\n");
                  
                      printf("Entrez un nombre : ");
                      scanf("%d", &nombre);
                      resultat = nombre;
                  
                      while (b_continuer)
                      {
                          printf("\nQuelle operation (+, -, *, /, c, q) : %d ", resultat);
                          operation = lireCaractere();
                  
                          switch(operation)
                          {
                              case '+':
                                  printf("Entrez un nombre : ");
                                  scanf("%d", &nombre);
                                  resultat += nombre;
                                  break;
                  
                              case '-':
                                  printf("Entrez un nombre : ");
                                  scanf("%d", &nombre);
                                  resultat -= nombre;
                                  break;
                  
                              case '*':
                                  printf("Entrez un nombre : ");
                                  scanf("%d", &nombre);
                                  resultat *= nombre;
                                  break;
                  
                              case '/':
                                  printf("Entrez un nombre : ");
                                  scanf("%d", &nombre);
                                  resultat /= nombre;
                                  break;
                  
                              case 'c':
                                  resultat = 0;
                                  break;
                  
                              case 'q':
                                  b_continuer = 0;
                                  break;
                  
                              default :
                                  printf("Merci de choisir une operation valide");
                                  break;
                          }
                      }
                  }
                  
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Lorsque l'on fait une recherche google, on tombe sur des forums qui nous disent de chercher sur google...
                    3 septembre 2010 à 19:50:15

                    Ton problème se situe au niveau de cette ligne là (qui ne supprime pas le '\n') : scanf("%d", &nombre);
                    Il faut donc vider le buffer après le scanf (cf la FAQ). :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      4 septembre 2010 à 1:24:10

                      Yop ! ^^

                      Je viens faire des vagues... Je poste ici la version console fraichement créée de mon parseur, nommé Equaminator. En fait, à la base, il avait été codé dans l'optique de construire un logiciel d'étude de courbes mathématiques (d'où le nom :p )
                      J'ai corrigé mon code et l'ai adapté à l'exercice :)

                      Comme d'habitude, les fonctionnalités sont énormes et le code classé horrible. Sans commentaire. :lol:
                      Vous pouvez télécharger le fichier Code::Blocks ici :
                      http://dl.free.fr/jCqxaZG3u/EquaminatorConsole.zip

                      Un aperçu rapide des fonctionnalités et propriétés principales :
                      • Gestion des opérateurs (+ - * / ^ !), priorités et parenthèses
                      • Multiplication implicite autorisée
                      • Nombreuses fonctions mathématiques, dont Intégrale de Riemann et résolution d'équations
                      • Variables et fonctions personnelles
                      • Au niveau du code, pas de pile, uniquement de la récursivité (ne m'en voulez pas pour la fonction Calculer()... :euh: )
                      • Dispatch tables pour la gestion des commandes, variables et fonctions par défaut

                      Pour de l'aide, commencez par taper help :D
                      Pour assigner une variable, entrez quelque chose comme var=acos(sqrt(3)/2).
                      Pour assigner une fonction, ce sera plus du genre f(x)=min(x,0), où le x est obligatoire à gauche.

                      Les matheux me pardonneront cette notation abusive, c'était le plus simple à gérer :p
                      Par ailleurs, l'abus se retrouve dans les fonctions par défaut drv, iteg et prmv. Le premier paramètre est une chaine du type f(x), le second la variable muette utilisée (ici x, donc). Pour les suivants, consultez l'aide !

                      Les variables (ou fonctions) ne contiennent pas des nombres mais des expressions. Ce qui signifie qu'elles sont en permanence reliées à l'objet dont on s'est éventuellement servi pour l'assigner. Un exemple très simple :

                      Image utilisateur

                      Ici, var2 ne vaut ni 1 ni 2 mais vaut var1. Si var1 change, var2 aussi. Si var1 est supprimé, var2 ne fonctionnera plus.
                      Le nombre maximal de niveaux est de 64.

                      Voilà, à vous maintenant ! Amusez-vous ;)


                      Edit :
                      Mise à jour du fichier. Correction de bugs dans la gestion des erreurs, ajout de la fonction solve() pour résoudre tout type d'équation (par recherche linéaire puis dichotomie).
                      • Partager sur Facebook
                      • Partager sur Twitter
                        5 septembre 2010 à 14:38:46

                        Citation : Pouet_forever

                        Ton problème se situe au niveau de cette ligne là (qui ne supprime pas le '\n') : scanf("%d", &nombre);
                        Il faut donc vider le buffer après le scanf (cf la FAQ).


                        Merci ! :) C'est fait.

                        Voici donc mon code pour la calculette débutant. Je vais maintenant réfléchir pour le niveau intermédiaire :
                        #include <stdio.h>
                        #include <stdlib.h>
                        
                        char lireCaractere();
                        void lancerCalculetteV1();
                        
                        int main(void)
                        {
                            int choix = 0;
                        
                            printf("Choisissez un mode de calculette : ");
                            scanf("%d", &choix);
                        
                            switch(choix)
                            {
                                case 1:
                                    lancerCalculetteV1();
                                    break;
                        
                                case 2:
                                    return 0;
                                    break;
                            }
                        
                            return 0;
                        }
                        
                        char lireCaractere()
                        {
                            char caractere = 0;
                        
                            caractere = getchar();
                            while (getchar() != '\n') ;
                        
                            return caractere;
                        }
                        
                        lancerCalculetteV1()
                        {
                            int b_continuer = 1;
                            int nombre = 0;
                            int resultat = 0;
                            char operation;
                        
                            printf("** ZCalc (niveau 1) **\n\n");
                        
                            printf("Entrez un nombre : ");
                            scanf ("%d", &nombre);
                            scanf ("%*[^\n]");
                            getchar ();
                            resultat = nombre;
                        
                            while (b_continuer)
                            {
                                printf("Quelle operation (+, -, *, /, c, q) : %d ", resultat);
                                operation = lireCaractere();
                        
                                switch(operation)
                                {
                                    case '+':
                                        printf("Entrez un nombre : ");
                                        scanf ("%d", &nombre);
                                        scanf ("%*[^\n]");
                                        getchar ();
                                        resultat += nombre;
                                        break;
                        
                                    case '-':
                                        printf("Entrez un nombre : ");
                                        scanf ("%d", &nombre);
                                        scanf ("%*[^\n]");
                                        getchar ();
                                        resultat -= nombre;
                                        break;
                        
                                    case '*':
                                        printf("Entrez un nombre : ");
                                        scanf ("%d", &nombre);
                                        scanf ("%*[^\n]");
                                        getchar ();
                                        resultat *= nombre;
                                        break;
                        
                                    case '/':
                                        printf("Entrez un nombre : ");
                                        scanf ("%d", &nombre);
                                        scanf ("%*[^\n]");
                                        getchar ();
                                        resultat /= nombre;
                                        break;
                        
                                    case 'c':
                                        resultat = 0;
                                        break;
                        
                                    case 'q':
                                        b_continuer = 0;
                                        break;
                        
                                    default :
                                        printf("Merci de choisir une operation valide");
                                        break;
                                }
                            }
                        }
                        

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Lorsque l'on fait une recherche google, on tombe sur des forums qui nous disent de chercher sur google...
                          5 septembre 2010 à 14:46:48

                          @VonDriguen : Plutôt que de commençer le niveau 2 tout de suite commence par améliorer ta solution pour le niveau 1 :

                          En programmation on doit éviter au maximum le copier coller or ces (celle surlignées) lignes sont parfaitement identiques et le break dans le cas par défaut est inutile. Ensuite le protype de la fonction lancerCalculetteV1 (ligne 38) est faux.
                          #include <stdio.h>
                          #include <stdlib.h>
                          
                          char lireCaractere();
                          void lancerCalculetteV1();
                          
                          int main(void)
                          {
                              int choix = 0;
                          
                              printf("Choisissez un mode de calculette : ");
                              scanf("%d", &choix);
                          
                              switch(choix)
                              {
                                  case 1:
                                      lancerCalculetteV1();
                                      break;
                          
                                  case 2:
                                      return 0;
                                      break;
                              }
                          
                              return 0;
                          }
                          
                          char lireCaractere()
                          {
                              char caractere = 0;
                          
                              caractere = getchar();
                              while (getchar() != '\n') ;
                          
                              return caractere;
                          }
                          
                          lancerCalculetteV1()
                          {
                              int b_continuer = 1;
                              int nombre = 0;
                              int resultat = 0;
                              char operation;
                          
                              printf("** ZCalc (niveau 1) **\n\n");
                          
                              printf("Entrez un nombre : ");
                              scanf ("%d", &nombre);
                              scanf ("%*[^\n]");
                              getchar ();
                              resultat = nombre;
                          
                              while (b_continuer)
                              {
                                  printf("Quelle operation (+, -, *, /, c, q) : %d ", resultat);
                                  operation = lireCaractere();
                          
                                  switch(operation)
                                  {
                                      case '+':
                                          printf("Entrez un nombre : ");
                                          scanf ("%d", &nombre);
                                          scanf ("%*[^\n]");
                                          getchar ();
                                          resultat += nombre;
                                          break;
                          
                                      case '-':
                                          printf("Entrez un nombre : ");
                                          scanf ("%d", &nombre);
                                          scanf ("%*[^\n]");
                                          getchar ();
                                          resultat -= nombre;
                                          break;
                          
                                      case '*':
                                          printf("Entrez un nombre : ");
                                          scanf ("%d", &nombre);
                                          scanf ("%*[^\n]");
                                          getchar ();
                                          resultat *= nombre;
                                          break;
                          
                                      case '/':
                                          printf("Entrez un nombre : ");
                                          scanf ("%d", &nombre);
                                          scanf ("%*[^\n]");
                                          getchar ();
                                          resultat /= nombre;
                                          break;
                          
                                      case 'c':
                                          resultat = 0;
                                          break;
                          
                                      case 'q':
                                          b_continuer = 0;
                                          break;
                          
                                      default :
                                          printf("Merci de choisir une operation valide");
                                          break;
                                  }
                              }
                          }
                          
                          • Partager sur Facebook
                          • Partager sur Twitter
                            6 septembre 2010 à 11:41:09

                            Citation : Lithrein

                            @VonDriguen : Plutôt que de commençer le niveau 2 tout de suite commence par améliorer ta solution pour le niveau 1 :
                            En programmation on doit éviter au maximum le copier coller or ces (celle surlignées) lignes sont parfaitement identiques et le break dans le cas par défaut est inutile. Ensuite le protype de la fonction lancerCalculetteV1 (ligne 38) est faux.



                            Pas de souci ! Je vais faire ça ! Au niveau du copier/coller, je pense avoir trouvé comment améliorer le code.

                            Et effectivement, j'ai oublié le void dans le prototype ligne 38... au temps pour moi :o
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Lorsque l'on fait une recherche google, on tombe sur des forums qui nous disent de chercher sur google...
                              18 septembre 2010 à 17:01:48

                              Salut :)

                              Un code pour la version avancée(sans l'opérateur puissance :-° ), mais avec les variables et les fonctions(certaines) de <math.h>

                              Ca pique un peu beaucoup les yeux, ça a des allures de chateau de carte, mais bon, ça à l'air de fonctionner(à peu près)

                              #include <stdio.h>
                              #include <stdlib.h>
                              #include <ctype.h>
                              #include <errno.h>
                              #include <math.h>
                              #include <string.h>
                              
                              #define MAXLEN  32
                              #define MAXVAR  16
                              
                              typedef struct clt Clt_t;
                              typedef double( *fp_t)(double);
                              
                              struct clt
                              {
                                  char str[BUFSIZ];
                                  char *p_str;
                                  struct var                      /* Variable */
                                  {
                                      char name[MAXLEN];          /* Nom de la variable */
                                      double v;                   /* Valeur */
                                  } var_a[MAXVAR];
                                  size_t nVar;                    /* Nombre de variables */
                                  int err;                        /* Code d'erreur */
                                  int done;                       /* Fini ? */
                                  double ans;                     /* Résultat précédent */
                              };
                              
                              
                              enum {  ERR_OK,
                                      ERR_NM_EXP,         /* Nombre attendu */
                                      ERR_BR_LFT,         /* ( attendue */
                                      ERR_FP_BAD,         /* Identifiant inconnu */
                                      ERR_VR_LNG,         /* Nom de variable trop long */
                                      ERR_VL_BAD,         /* Valeur incorrecte */
                                      ERR_LN_LEN,         /* Ligne trop longue */
                                      ERR_SB_BAD,          /* Symbole inattendu */
                                      ERR_BR_RGT,          /* Parenthèse droite manquante */
                                      ERR_VR_NM            /* Nombre de variable trop important */
                                   };
                              
                              Clt_t *Clt_new(void);
                              void Clt_delete(Clt_t *p_self);
                              void Clt_run(Clt_t *p_self);
                              
                              /* Private functions -------------------------------------------------------- */
                              void readDbl( Clt_t *p_self, double *x );
                              void readWrd( Clt_t *p_self, char *buf);
                              
                              static void clear(Clt_t *p_self);
                              static void findNxtChr(Clt_t *p_self);
                              static void calc(Clt_t *p_self);
                              
                              static void expr(Clt_t *p_self, double *v);
                              static void term(Clt_t *p_self, double *v);
                              static void fact(Clt_t *p_self, double *v);
                              static void num(Clt_t *p_self, double *v);
                              
                              static void word(Clt_t *p_self, double *v);
                              static void varSet(Clt_t *p_self, char const *name, double *v);
                              static void varGet(Clt_t *p_self, char const *name, double *v);
                              /* Interface ---------------------------------------------------------------- */
                              Clt_t *Clt_new(void)
                              {
                                  Clt_t *p_new = malloc(sizeof *p_new);
                                  if(p_new == NULL)
                                  {
                                      fprintf(stdin, "out of memory !");
                                      exit(EXIT_FAILURE);
                                  }
                              
                                  p_new->str[0] = '\0';
                                  p_new->p_str = p_new->str;
                                  clear(p_new);
                              
                                  p_new->done = 0;
                              
                                  return p_new;
                              }
                              
                              
                              
                              void Clt_delete(Clt_t *p_self)
                              {
                                  free(p_self);
                              }
                              
                              
                              void Clt_run(Clt_t *p_self)
                              {
                                  puts("(Q)uit, (C)lear");
                                  while(!p_self->done)
                                  {
                                      p_self->err = ERR_OK;
                                      p_self->p_str = p_self->str;
                                      putchar('>');
                                      if(fgets(p_self->p_str, BUFSIZ, stdin) != NULL)
                                      {
                                          char *p = strchr(p_self->p_str, '\n');
                                          {
                                              if(p != NULL)
                                              {
                                                  *p = '\0';
                                              }
                                              else
                                              {
                                                  /* line too long */
                                                  p_self->err = ERR_LN_LEN;
                                              }
                                          }
                                      }
                                      calc(p_self);
                                  }
                              }
                              
                              
                              void clear(Clt_t *p_self)
                              {
                                  size_t i;
                                  for(i = 0; i < MAXVAR; i++)
                                  {
                                      p_self->var_a[i].name[0] = '\0';
                                      p_self->var_a[i].v = 0.;
                                  }
                                  p_self->nVar = 0;
                                  p_self->ans = 0;
                                  p_self->err = ERR_OK;
                              }
                              
                              
                              
                              void calc(Clt_t *p_self)
                              {
                                  char const *errors[] =
                                  {
                                      "",
                                      "Nombre attendu.",
                                      "( attendue.",
                                      "identifiant inconnu",
                                      "Nom de variable trop long",
                                      "Valeur incorrecte",
                                      "ligne trop longue",
                                      "symbole inattendu",
                                      ") attendue.",
                                      "Nombre de variables trop important."
                                  };
                              
                              
                                  expr(p_self, &(p_self->ans));
                                  if(!p_self->done)
                                  {
                                      findNxtChr(p_self);
                                      if(!p_self->err && *p_self->p_str != '\0')
                                          p_self->err = ERR_SB_BAD;
                                      if (p_self->err)
                                      {
                                          printf("Expression incorrecte : %s\n", errors[p_self->err]);
                                          p_self->ans = 0;
                                      }
                                      else
                                          printf("%g\n", p_self->ans);
                                  }
                              }
                              
                              
                              /* Retourne le prochain caractère "utile" de l'expression */
                              void findNxtChr(Clt_t *p_self)
                              {
                                  while (isspace((unsigned char)*p_self->p_str))
                                      p_self->p_str++;
                              }
                              
                              
                              
                              void expr(Clt_t *p_self, double *v)
                              {
                                  if (!p_self->err)
                                      term(p_self, v);
                                  if (!p_self->err)
                                  {
                                      findNxtChr(p_self);
                                      while(1)
                                      {
                                          double aux = 0;
                                          int op = *p_self->p_str;
                              
                                          switch (op)
                                          {
                                          case '+':
                                              p_self->p_str++;
                                              findNxtChr(p_self);
                                              term(p_self, &aux);
                                              if (!p_self->err)
                                                  *v += aux;
                                              break;
                                          case '-':
                                              p_self->p_str++;
                                              findNxtChr(p_self);
                                              term(p_self, &aux);
                                              if (!p_self->err)
                                                  *v -= aux;
                                              break;
                                          default:
                                              return;
                                          }
                              
                                      }
                              
                                  }
                              }
                              
                              
                              void term(Clt_t *p_self, double *v)
                              {
                                  findNxtChr(p_self);
                                  if (!p_self->err)
                                      fact(p_self, v);
                                  if (!p_self->err)
                                  {
                                      findNxtChr(p_self);
                                      while(1)
                                      {
                                          double aux = 0;
                                          int op = *p_self->p_str;
                              
                                          switch (op)
                                          {
                                          case '*':
                                              p_self->p_str++;
                                              findNxtChr(p_self);
                                              fact(p_self, &aux);
                                              if (!p_self->err)
                                                  *v *= aux;
                                              break;
                                          case '/':
                                              p_self->p_str++;
                                              findNxtChr(p_self);
                                              fact(p_self, &aux);
                                              if (!p_self->err)
                                                  *v /= aux;
                                              break;
                              
                                          default:
                                              return;
                                          }
                              
                                      }
                              
                                  }
                              }
                              
                              
                              
                              
                              void fact(Clt_t *p_self, double *v)
                              {
                                  int neg = 0;
                              
                                  if (*p_self->p_str == '-')
                                  {
                                      neg = 1;
                                      p_self->p_str++;
                                      findNxtChr(p_self);
                                  }
                              
                                  if (*p_self->p_str == '(')
                                  {
                                      p_self->p_str++;
                                      findNxtChr(p_self);
                                      expr(p_self, v);
                              
                                      if (*p_self->p_str != ')')
                                          p_self->err = ERR_BR_RGT;
                              
                                      p_self->p_str++;
                                      findNxtChr(p_self);
                                  }
                                  else
                                      num(p_self, v);
                                  if (neg)
                                      *v = -(*v);
                                  findNxtChr(p_self);
                              }
                              
                              
                              
                              void readDbl( Clt_t *p_self, double *x )
                              {
                                  errno = 0;
                                  *x = strtod( p_self->p_str, &p_self->p_str );
                                  if ( errno == ERANGE )
                                      p_self->err = ERR_VL_BAD;
                              }
                              
                              
                              void readWrd( Clt_t *p_self, char *buf)
                              {
                                  char *pbuf = buf;
                                  while(isalnum((unsigned char)*p_self->p_str))
                                      *pbuf++ = *p_self->p_str++;
                                  *pbuf = '\0';
                              }
                              
                              
                              void word(Clt_t *p_self, double *v)
                              {
                                  static struct
                                  {
                                      char const *name;
                                      fp_t fp;
                                  } fun[] =
                                  {
                                      {"cos", cos},
                                      {"sin", sin},
                                      {"acos", acos},
                                      {"asin", asin},
                                      {"atan", atan},
                                      {"exp", exp},
                                      {"log", log},
                                      {"log10", log10},
                                      {"fabs", fabs},
                                      {"floor", floor},
                                      {"sqrt", sqrt},
                                      {NULL, NULL}
                                  };
                                  char buf[BUFSIZ];
                              
                                  readWrd(p_self, buf);
                                  if(strcmp("q", buf) == 0 || strcmp("Q", buf) == 0)
                                      p_self->done = 1;
                                  else if(strcmp("c", buf) == 0 || strcmp("C", buf) == 0)
                                      clear(p_self);
                                  else if(strcmp("ans", buf) == 0)
                                      *v = p_self->ans;
                                  else
                                  {
                                      size_t i;
                                      for(i = 0; fun[i].name != NULL && strcmp(fun[i].name, buf) != 0; i++ )
                                          ;
                              
                                      if(fun[i].name != NULL)
                                      {
                                          double arg = 0;
                              
                                          findNxtChr(p_self);
                                          if(*p_self->p_str == '(')
                                          {
                                              p_self->p_str++;
                                              findNxtChr(p_self);
                                              expr(p_self, &arg);
                              
                                              if (*p_self->p_str != ')')
                                                  p_self->err = ERR_BR_RGT;
                                              if(!p_self->err)
                                                  *v = fun[i].fp(arg);
                                              p_self->p_str++;
                                          }
                                          else
                                              p_self->err = ERR_BR_LFT;
                                      }
                                      else
                                      {
                                          findNxtChr(p_self);
                                          if(*p_self->p_str == '=')
                                          {
                                              p_self->p_str++;
                                              varSet(p_self, buf, v);
                                          }
                                          else
                                          {
                                              varGet(p_self, buf, v);
                                          }
                                      }
                                  }
                              }
                              
                              
                              void num(Clt_t *p_self, double *v)
                              {
                                  if(isdigit((unsigned char)*(p_self->p_str)) || *(p_self->p_str) == '.')
                                  {
                                      readDbl(p_self, v);
                                  }
                                  else if(isalpha((unsigned char)*(p_self->p_str)))
                                  {
                                      word(p_self, v);
                                  }
                                  else
                                  {
                                      p_self->err = ERR_NM_EXP;
                                  }
                              }
                              
                              /* Définition, affectation d'une variable */
                              void varSet(Clt_t *p_self, char const *name, double *v)
                              {
                                  size_t i;
                                  if(p_self->nVar >= MAXVAR)
                                      p_self->err = ERR_VR_NM;
                                  else
                                  {
                                      for(i = 0; i < p_self->nVar && strcmp(p_self->var_a[i].name, name) != 0; i++)
                                          ;
                                      if(i == p_self->nVar)
                                      {
                                          size_t len = strlen(name);
                              
                                          if(len < MAXLEN)
                                          {
                                              /* Définition */
                                              strncpy(p_self->var_a[p_self->nVar].name, name, len + 1);
                                              p_self->nVar++;
                                          }
                                          else
                                          {
                                              /* Nom de variable trop long */
                                              p_self->err = ERR_VR_LNG;
                                          }
                                      }
                              
                                      /* Affectation */
                                      if(!p_self->err)
                                      {
                                          expr(p_self, &p_self->var_a[i].v);
                                          if(!p_self->err)
                                          {
                                              *v = p_self->var_a[i].v;
                                              findNxtChr(p_self);
                                          }
                                      }
                                  }
                              }
                              
                              
                              void varGet(Clt_t *p_self, char const *name, double *v)
                              {
                                  size_t i;
                                  for(i = 0; i < p_self->nVar && strcmp(p_self->var_a[i].name, name) != 0; i++)
                                      ;
                                  if(i != p_self->nVar)
                                  {
                                      *v = p_self->var_a[i].v;
                                  }
                                  else
                                  {
                                      p_self->err = ERR_FP_BAD;
                                  }
                              }
                              
                              int main(void)
                              {
                                  Clt_t *calculator = Clt_new();
                                  Clt_run(calculator);
                              
                                  Clt_delete(calculator), calculator = NULL;
                              
                                  return EXIT_SUCCESS;
                              }
                              



                              Et ça permet de remonter le topic. :D

                              edit: correction du bazar.
                              edit2: correction d'un problème sur les expression style 2 * 3 * 5.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Zeste de Savoir, le site qui en a dans le citron !
                                18 septembre 2010 à 23:50:45

                                Citation : GurneyH


                                Ca pique un peu beaucoup les yeux, ça a des allures de chateau de carte, mais bon, ça à l'air de fonctionner(à peu près)




                                candide@~$ ./x
                                (Q)uit, (C)lear
                                >sqrt(42*42)
                                42
                                >2+3
                                5
                                >sin
                                5
                                >(5*4-2*(8-(3-(4-4*4)*9)-2)+12)*56
                                11760
                                >q
                                candide@~$ python -c "print (5*4-2*(8-(3-(4-4*4)*9)-2)+12)*56"
                                13552
                                candide@~$
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  19 septembre 2010 à 6:00:20

                                  C'est bien un château de carte.

                                  Je corrigerai(j'essaierai de corriger. :-° ) bientôt. Là je ne peux plus voir cette calculatrice en photo.

                                  edit:
                                  J'ai corrigé le gros morceau je pense. :-°(mais le code est toujours aussi laid)
                                  Post précédent édité.

                                  Si vous trouvez d'autres problèmes je suis preneur. Merci.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Zeste de Savoir, le site qui en a dans le citron !
                                    2 octobre 2010 à 12:37:18

                                    Alors voilà le code du niveau 1 pour moi.
                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    
                                    char getchar_sec() // getchar ne récupère que les caractères voulus
                                    {
                                        char c = 0;
                                        do
                                        {
                                            c = 0;
                                            c = getchar();
                                        }while (c != '+' && c != '-' && c != '*' && c != '/' && c != 'c' && c != 'q');
                                        return c;
                                    }
                                    
                                    
                                    int main()
                                    {
                                        char charget = '+'; // Le char obtenu avec getchar
                                        double a = 0, b = 0;
                                    
                                        printf("*****  Zcalc  (niveau 1)  *****\n\n");
                                    
                                        while (charget != 'q') // on sort de la boucle si on a voulu quitter
                                        {
                                            printf("Entrez un nombre : ");
                                            scanf("%lf", &a);
                                    
                                        switch (charget)
                                        {
                                            case '+':
                                            b += a;
                                            break;
                                    
                                            case '-':
                                            b -= a;
                                            break;
                                    
                                            case '*':
                                            b *= a;
                                            break;
                                    
                                            case '/':
                                            b /= a;
                                            break;
                                    
                                            case 'c':
                                            b = a;
                                            break;
                                            default:
                                            printf("%c", charget);
                                            break;
                                        }
                                            a = b;
                                            printf("Choisissez une operation (+, -, *, /, c , q) : %f ", a);
                                            charget = getchar_sec();
                                        }
                                    
                                        return EXIT_SUCCESS;
                                    }
                                    

                                    Entrez un nombre : 50.25
                                    Choisissez une operation (+, -, *, /, c , q) : 50.250000 +
                                    Entrez un nombre : 0.75
                                    Choisissez une operation (+, -, *, /, c , q) : 51.000000 -
                                    Entrez un nombre : 1
                                    Choisissez une operation (+, -, *, /, c , q) : 50.000000 *
                                    Entrez un nombre : 2
                                    Choisissez une operation (+, -, *, /, c , q) : 100.000000 /
                                    Entrez un nombre : 4
                                    Choisissez une operation (+, -, *, /, c , q) : 25.000000 c
                                    Entrez un nombre : 45
                                    Choisissez une operation (+, -, *, /, c , q) : 45.000000 q



                                    J'ai une choses à dire concernant ce code. Quand je fais une division par 0, la console m'affiche que la variable a vaut "1.#INF00". Je voudrais savoir comment récupérer cette valeur pour faire un gestion d'erreur personnalisée.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      2 octobre 2010 à 13:10:12

                                      Ma contribution :

                                      #include <stdlib.h>
                                      #include <stdio.h>
                                      
                                      enum type_oper {
                                          MULTIPLICATION,
                                          DIVISION,
                                          SOUSTRACTION,
                                          ADDITION
                                      };
                                      
                                      void donner_type_oper( char choix,  enum type_oper *type_de_loperation );
                                      double effectue_operation( enum type_oper type_de_loperation, double a, double b );
                                      char get_op( double nb1);
                                      
                                      int main()
                                      {
                                          double nb1 = 0, nb2= 0;
                                          char oper = ' ';
                                          enum type_oper type_de_loperation;
                                      
                                      //---------------------------
                                          printf( "** zCalc (niv. 1) / par Lepetitzero **\n\n");
                                          printf("Entrez un nombre :") ;
                                          scanf("%lf", &nb1);
                                      
                                          while( 1 ){
                                      
                                              oper = get_op( nb1 );
                                              if( oper == 'q' ) return 1;
                                              if( oper == 'c' ) nb1 = nb2 = 0;
                                      
                                              donner_type_oper( oper, &type_de_loperation );
                                      
                                              printf("Entrez un nombre :") ;
                                              scanf("%lf", &nb2);
                                              nb1 = effectue_operation( type_de_loperation, nb1, nb2 );
                                      
                                          }
                                      
                                      
                                      
                                          return 0;
                                      }
                                      
                                      char get_op( double nb1){
                                      
                                          printf("Quelle operation ( +, -, *, /, c, q )? => %lf", nb1 );
                                          fflush(stdin); // vide le buffer
                                          return getchar( );
                                      
                                      }
                                      
                                      
                                      double effectue_operation( enum type_oper type_de_loperation, double a, double b )
                                      {
                                          switch ( type_de_loperation ){
                                              case ADDITION:
                                                  return a+b;
                                              break;
                                      
                                              case SOUSTRACTION:
                                                  return a-b;
                                              break;
                                      
                                              case DIVISION:
                                                  if( b == 0 ){
                                                      printf( "Division par 0 impossible !\n");;
                                                      return 1;
                                                  }
                                                  else
                                                      return a/b;
                                              break;
                                      
                                              case MULTIPLICATION :
                                                  return a*b;
                                              break;
                                      
                                              default: return b; break;
                                          }
                                      
                                      
                                      }
                                      
                                      void donner_type_oper( char choix,  enum type_oper *type_de_loperation )
                                      {
                                          switch( choix ){
                                              case '+':
                                                  *type_de_loperation = ADDITION;
                                              break;
                                      
                                              case '-':
                                                  *type_de_loperation = SOUSTRACTION;
                                              break;
                                      
                                              case '/':
                                                  *type_de_loperation = DIVISION;
                                              break;
                                      
                                              case '*':
                                                  *type_de_loperation = MULTIPLICATION;
                                              break;
                                      
                                              default:
                                                   printf("Veuillez entrer une operation valide !\n");
                                              break;
                                      
                                          }
                                      
                                      }
                                      

                                      Bien sûr j'ai fait le niveau débutant, je ne sais pas comment on parse les expressions :'(
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        2 octobre 2010 à 20:39:44

                                        Citation : nasta

                                        Je voudrais savoir comment récupérer cette valeur pour faire un gestion d'erreur personnalisée.


                                        Le plus sage, et c'est une attitude mathématique, est de ne pas diviser par zéro, plutôt que d'attendre qu'une machine te signale gentiment que ce que tu as demandé est absurde :p
                                        Personnellement, je te conseille donc de faire ta gestion d'erreur avant l'opération...
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          2 octobre 2010 à 22:28:12

                                          Citation : CokieForever

                                          Citation : nasta

                                          Je voudrais savoir comment récupérer cette valeur pour faire un gestion d'erreur personnalisée.


                                          Le plus sage, et c'est une attitude mathématique, est de ne pas diviser par zéro, plutôt que d'attendre qu'une machine te signale gentiment que ce que tu as demandé est absurde :p
                                          Personnellement, je te conseille donc de faire ta gestion d'erreur avant l'opération...


                                          Je me rend compte que j'ai oublié ce point... :'(

                                          edit:
                                          @Lithrein: c'était un bel exo pour tous niveaux...
                                          chapeau, vraiment!
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Zeste de Savoir, le site qui en a dans le citron !
                                            15 octobre 2010 à 22:00:10

                                            Hop, aller une nouvelle caltos pour la route ! Je me suis basé sur l'ancienne mais j'ai géré les erreurs de syntaxe cette fois. :)
                                            Dites moi ce que vous en pensez :

                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            #include <ctype.h>
                                            #include <string.h>
                                            #include <errno.h>
                                            #include <math.h>
                                            
                                            
                                            #pragma mark MACRO
                                            /* **************** Macro **************** */
                                            
                                            #define CHECK_PUSH_STACK(stack, val, type)    \
                                            do {                                          \
                                            if (pushStack(stack, val, type) < 0)       \
                                            return -1;                                \
                                            } while (0)
                                            
                                            #define CHECK_POP_STACK(affect, stack)        \
                                            do {                                          \
                                            int type_MCPS;                              \
                                            affect = popStack(stack, &type_MCPS);      \
                                            if (type_MCPS == C_NOOP)                    \
                                            return -1;                                \
                                            } while (0)
                                            
                                            #pragma mark CONSTANT
                                            /* **************** Constant **************** */
                                            
                                            #define N_MAX     100
                                            #define SZ_NAME   50
                                            
                                            enum {
                                              E_OK,       /* No error                 */
                                              E_VAFF,     /* Affectation error        */
                                              E_BRAC,     /* Bracket error            */
                                              E_ARGS,     /* Number of arguments      */
                                              E_OPER,     /* Operator error           */
                                              E_OPAG,     /* Operator havn't 2 oprands*/
                                              E_VARN,     /* Variable name error      */
                                              E_LENV,     /* Variable name too long   */
                                              E_UERR,     /* Unexpected error         */
                                              E_FUNC,     /* Function call error      */
                                              E_VARE,     /* Variable does not exist  */
                                              E_STKF,     /* Stack full               */
                                              E_STKE,     /* Stack empty              */
                                              E_MALC,     /* Malloc error             */
                                              E_OPUK,     /* Unknown operator         */
                                              E_VARA,     /* Non modifiable variable  */
                                              E_DIV0,     /* Divide by 0              */
                                              E_OPCO,     /* Operator ',' not in func */
                                              E_NUMB,     /* 2 numbers                */
                                              N_ERRS      /* Number of errors         */
                                            };
                                            
                                            enum {
                                              C_NOOP,
                                              C_OPER,
                                              C_NUM,
                                              C_VAR,
                                              C_FUNC,
                                              C_AFFECT
                                            };
                                            
                                            #pragma mark STRUCTURE/UNION
                                            /* **************** Structure **************** */
                                            
                                            typedef struct stack_s {
                                              int st[N_MAX][2];           /* Stack : [0] -> Value, [1] -> type  */
                                              char name[N_MAX][SZ_NAME];  /* Variable name                      */
                                              int i;                      /* Index                              */
                                            } stack;
                                            
                                            typedef struct n_stack_s {
                                              stack st[2];
                                            } n_stack;
                                            
                                            typedef struct llist_val_s {
                                              struct llist_val_s * nxt;
                                              int val;                  /* Value  */
                                              char name[SZ_NAME];       /* Name   */
                                            } llist_val;
                                            
                                            typedef struct llist_s {
                                              llist_val * ans;
                                              llist_val * begin;
                                              llist_val * end;
                                              llist_val * add; /* Number of variable for affectation */
                                            } llist;
                                            
                                            typedef struct state_s {
                                              int affect;
                                              int current;
                                              int val_cur_op;
                                              int sig;
                                              int func;
                                            } estate;
                                            
                                            typedef struct funcs_s {
                                              char * name;
                                              int args;
                                            } funcs;
                                            
                                            typedef union {
                                              int val;
                                              char * name;
                                            } type_u;
                                            
                                            #pragma mark GLOBAL
                                            /* **************** Global **************** */
                                            
                                            llist list_g;
                                            int error;
                                            
                                            char * s_error[N_ERRS] = {
                                              "",
                                              "Affectation error",
                                              "Bracket error",
                                              "Invalid number of arguments",
                                              "Two operators which follow",
                                              "Operator must have 2 operands",
                                              "Incorrect variable name",
                                              "Variable name too long",
                                              "Unexpected error",
                                              "Function call",
                                              "Variable does not exist",
                                              "Stack full, expression too long",
                                              "Stack empty",
                                              "Malloc error",
                                              "Unknown operator",
                                              "Non modifiable variable",
                                              "Divide by 0",
                                              "Operator ',' must be in function call",
                                              "Two number which follow"
                                            };
                                            
                                            char * s_reservedName[] = {
                                              "q", "quit",
                                              "c", "clear",
                                              "h", "help",
                                              NULL
                                            };
                                            
                                            #define N_FUNC_1_ARG    9
                                            
                                            funcs func_call[] = {
                                              { "cos"   , 1 },
                                              { "sin"   , 1 },
                                              { "tan"   , 1 },
                                              { "fabs"  , 1 },
                                              { "exp"   , 1 },
                                              { "log"   , 1 },
                                              { "log10" , 1 },
                                              { "log2"  , 1 },
                                              { "sqrt"  , 1 },
                                              { "pow"   , 2 },
                                              { "hypot" , 2 },
                                              { NULL    , 0 }
                                            };
                                            
                                            double (*f1[])(double) = {
                                              cos, sin, tan, fabs, exp, log, log10, log2, sqrt
                                            };
                                            double (*f2[])(double, double) = {
                                              pow, hypot
                                            };
                                            
                                            #pragma mark PROTOTYPE
                                            /* **************** Prototype **************** */
                                            
                                            char * calcGetError(void);
                                            void calcSetError(int err);
                                            void printError(char const * s);
                                            
                                            llist_val * searchLlist(llist * l, char * name);
                                            llist * pushLlist(llist * l, llist_val * val);
                                            llist * popLlist(llist * l);
                                            
                                            int pushStack(stack * st, type_u var, int type);
                                            type_u popStack(stack * st, int * type);
                                            int popAllStack(n_stack * st);
                                            
                                            char * skipSpace(char * s);
                                            void delEnter(char * s);
                                            
                                            char * getVar(char * s, char * name);
                                            int checkVar(char * s, int * n);
                                            int applyVar(char ** src, estate * state, n_stack * st, char * var);
                                            int handleVar(char * src, char ** dst, estate * state, n_stack * st);
                                            int handleFunc(char * src, char ** dst, estate * state, n_stack * st, int n_f);
                                            
                                            int isOper(int c);
                                            int setPrio(int op);
                                            int priority(int op1, int op2);
                                            int handleOper(char * src, char ** dst, estate * state, n_stack * st);
                                            
                                            int convertNPI(char * src, char ** dst, n_stack * st, estate * state);
                                            int calcNPI(stack * st);
                                            int calcExp(char * s);
                                            void printHelp(void);
                                            int evaluate(char * s);
                                            int prompt(void);
                                            void release_llist(void);
                                            int init(void);
                                            
                                            #pragma mark FUNCTION
                                            /* **************** Function **************** */
                                            
                                            #pragma mark Errors
                                            /* >> Gestion d'erreur << */
                                            
                                            char * calcGetError(void) {
                                              return s_error[error];
                                            }
                                            
                                            void calcSetError(int err) {
                                              if (err < 0 || err >= N_ERRS)
                                                return;
                                              error = err;
                                            }
                                            
                                            void printError(char const * s) {
                                              if (s != NULL)
                                                fprintf(stderr, "%s ", s);
                                              fprintf(stderr, "%s\n", calcGetError());
                                            }
                                            
                                            #pragma mark Linked lists
                                            /* >> Gestion de la liste chaînée << */
                                            
                                            llist_val * searchLlist(llist * l, char * name) {
                                              llist_val * tmp;
                                              
                                              if (!l)
                                                return NULL;
                                              
                                              tmp = l->begin;
                                              while (tmp != NULL && strcmp(tmp->name, name)) {
                                                tmp = tmp->nxt;
                                              }
                                              if (tmp == NULL)
                                                calcSetError(E_VARE);
                                              
                                              return tmp;
                                            }
                                            
                                            llist * pushLlist(llist * l, llist_val * val) {
                                              llist_val * new;
                                              
                                              if (!l)
                                                return NULL;
                                              
                                              new = malloc(sizeof *new);
                                              if (!new) {
                                                calcSetError(E_MALC);
                                                return NULL;
                                              }
                                              
                                              new->nxt = NULL;
                                              new->val = val->val;
                                              strcpy(new->name, val->name);
                                              
                                              if (l->begin == NULL) {
                                                l->begin = new;
                                                l->end = new;
                                              }
                                              else {
                                                l->end->nxt = new;
                                                l->end = new;
                                              }
                                              return l;
                                            }
                                            
                                            llist * popLlist(llist * l) {
                                              llist_val * tmp;
                                              
                                              if (!l || !l->begin)
                                                return NULL;
                                              
                                              tmp = l->begin->nxt;
                                              free(l->begin);
                                              l->begin = tmp;
                                              return l;
                                            }
                                            
                                            #pragma mark Stacks
                                            /* >> Gestion de la pile << */
                                            
                                            int pushStack(stack * st, type_u var, int type) {
                                              
                                              if (((type == C_VAR || type == C_FUNC) && var.name == NULL) ||
                                                  st == NULL)
                                                return -1;
                                              
                                              if (st->i >= N_MAX-1) {
                                                calcSetError(E_STKF);
                                                return -1;
                                              }
                                              
                                              if (type == C_VAR) {
                                                st->st[st->i][0] = 'V';
                                                strcpy(st->name[st->i], var.name);
                                              }
                                              else if (type == C_AFFECT) {
                                                st->st[st->i][0] = '=';
                                                strcpy(st->name[st->i], var.name);
                                              }
                                              else if (type == C_NUM || type == C_OPER || type == C_FUNC)
                                                st->st[st->i][0] = var.val;
                                              
                                              st->st[st->i][1] = type;
                                              st->i++;
                                              
                                              return 0;
                                            }
                                            
                                            type_u popStack(stack * st, int * type) {
                                              type_u tmp;
                                              int tmp_type;
                                              int i;
                                              
                                              if (st->i <= 0) {
                                                *type = C_NOOP;
                                                calcSetError(E_STKE);
                                                tmp.val = 0;
                                                return tmp;
                                              }
                                              
                                              i = st->i - 1;
                                              tmp_type = st->st[i][1];
                                              
                                              if (tmp_type == C_OPER || tmp_type == C_NUM || tmp_type == C_FUNC) {
                                                *type = tmp_type;
                                                tmp.val = st->st[i][0];
                                              }
                                              else if (tmp_type == C_VAR || tmp_type == C_AFFECT) {
                                                *type = tmp_type;
                                                tmp.name = st->name[i];
                                              }
                                              else {
                                                *type = C_NOOP;
                                                calcSetError(E_OPER);
                                                tmp.val = 0;
                                                return tmp;
                                              }
                                              
                                              st->st[i][0] = 0;
                                              st->st[i][1] = C_NOOP;
                                              st->i--;
                                              
                                              return tmp;
                                            }
                                            
                                            int popAllStack(n_stack * st) {
                                              type_u v;
                                              int type;
                                              
                                              while (1) {
                                                v = popStack(&st->st[1], &type);
                                                if (type == C_NOOP)
                                                  break;
                                                if (pushStack(&st->st[0], v, type) < 0)
                                                  return -1;
                                              }
                                              /* La pile 2 est vide : error est set à E_NOOP */
                                              calcSetError(E_OK);
                                              return 0;
                                            }
                                            
                                            #pragma mark Strings
                                            /* >> Fonctions sur les chaînes de caractères << */
                                            
                                            char * skipSpace(char * s) {
                                              while (isspace(*s))
                                                s++;
                                              return s;
                                            }
                                            
                                            void delEnter(char * s) {
                                              char * c = strchr(s, '\n');
                                              
                                              if (c)
                                                *c = '\0';
                                            }
                                            
                                            #pragma mark Variables & functions
                                            /* >> Gestion des variables et fonctions << */
                                            
                                            char * getVar(char * s, char * name) {
                                              int i;
                                              
                                              i = 0;
                                              while (isalnum(*s) && i < SZ_NAME) {
                                                name[i] = *s;
                                                s++;
                                                i++;
                                              }
                                              
                                              if (i >= SZ_NAME) {
                                                calcSetError(E_LENV);
                                                return NULL;
                                              }
                                              
                                              name[i] = '\0';
                                              return s;
                                            }
                                            
                                            int checkVar(char * s, int * n) {
                                              char ** tmp;
                                              int i;
                                              
                                              for (i = 0; func_call[i].name != NULL; i++) {
                                                if (strcmp(func_call[i].name, s) == 0) {
                                                  *n = i;
                                                  return C_FUNC;
                                                }
                                              }
                                              
                                              tmp = s_reservedName;
                                              while (*tmp != NULL) {
                                                if (strcmp(*tmp, s) == 0) {
                                                  calcSetError(E_VARN);
                                                  return C_NOOP;
                                                }
                                                tmp++;
                                              }
                                              
                                              return C_VAR;
                                            }
                                            
                                            int applyVar(char ** src, estate * state, n_stack * st, char * var) {
                                              type_u v;
                                              
                                              /* Affectation */
                                              if (*(*src) == '=' && state->affect) {
                                                if (strcmp(var, "ans") == 0) {
                                                  calcSetError(E_VARA);
                                                  return -1;
                                                }
                                                (*src)++;
                                                v.name = var;
                                                CHECK_PUSH_STACK(&st->st[1], v, C_AFFECT);
                                                state->current = C_AFFECT;
                                              }
                                              /* Affectation error */
                                              else if (*(*src) == '=' && !state->affect) {
                                                calcSetError(E_VAFF);
                                                return -1;
                                              }
                                              /* Variable */
                                              else {
                                                llist_val * var_l;
                                                
                                                if (strcmp(var, "ans") == 0)
                                                  var_l = list_g.ans;
                                                else
                                                  var_l = searchLlist(&list_g, var);
                                                
                                                if (var_l == NULL) {
                                                  return -1;
                                                }
                                                /* Variable exists */
                                                else {
                                                  if (state->current == C_NOOP || state->current == C_OPER ||
                                                      state->current == C_AFFECT) {
                                                    v.val = var_l->val;
                                                    CHECK_PUSH_STACK(&st->st[0], v, C_NUM);
                                                    state->current = C_NUM;
                                                    state->affect = 0;
                                                  }
                                                  else {
                                                    calcSetError(E_OPER);
                                                    return -1;
                                                  }
                                                }
                                              }
                                              return 0;
                                            }
                                            
                                            int handleVar(char * src, char ** dst, estate * state, n_stack * st) {
                                              char var[SZ_NAME];
                                              int chk, n_f;
                                              
                                              src = getVar(src, var);
                                              if (src == NULL)
                                                return -1;
                                              
                                              chk = checkVar(var, &n_f);
                                              if (chk == C_NOOP)
                                                return -1;
                                              
                                              src = skipSpace(src);
                                              
                                              /* Variable */
                                              if (chk == C_VAR) {
                                                if (applyVar(&src, state, st, var) < 0)
                                                  return -1;
                                              }
                                              /* Function */
                                              else if (chk == C_FUNC) {
                                                if (*src == '(') {
                                                  if (handleFunc(src, &src, state, st, n_f) < 0)
                                                    return -1;
                                                }
                                                /* Function error */
                                                else {
                                                  calcSetError(E_FUNC);
                                                  return -1;
                                                }
                                              }
                                              /* Should never happen */
                                              else {
                                                return -1;
                                              }
                                              
                                              if (dst != NULL)
                                                *dst = src;
                                              return 0;
                                            }
                                            
                                            int handleFunc(char * src, char ** dst, estate * state, n_stack * st, int n_f) {
                                              int i, tmp, type, nb_args;
                                              type_u v;
                                              
                                              state->func = 1;
                                              state->current = C_OPER;
                                              state->val_cur_op = *src;
                                              src++;
                                              
                                              nb_args = func_call[n_f].args;
                                              for (i = 0; i < nb_args; i++) {
                                                v.val = '(';
                                                CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                
                                                state->affect = 1;
                                                state->current = C_OPER;
                                                state->val_cur_op = '(';
                                                
                                                convertNPI(src, &src, st, state);
                                                if (error != E_OK)
                                                  return -1;
                                                
                                                src = skipSpace(src);
                                                if ((i < nb_args - 1 && *src != ',') && (i == nb_args - 1 && *src != ')')) {
                                                  calcSetError(E_BRAC);
                                                  return -1;
                                                }
                                                src++;
                                                
                                                tmp = st->st[1].i;
                                                while (st->st[1].st[tmp-1][0] != '(') {
                                                  v = popStack(&st->st[1], &type);
                                                  if (type == C_NOOP)
                                                    return -1;
                                                  CHECK_PUSH_STACK(&st->st[0], v, type);
                                                  tmp = st->st[1].i;
                                                }
                                                /* Bracket */
                                                popStack(&st->st[1], &type);
                                              }
                                              
                                              v.val = n_f;
                                              CHECK_PUSH_STACK(&st->st[0], v, C_FUNC);
                                              
                                              state->func = 0;
                                              if (dst != NULL)
                                                *dst = src;
                                              return 0;
                                            }
                                            
                                            #pragma mark Operators
                                            /* >> Gestion des opérateurs << */
                                            
                                            int isOper(int c) {
                                              char oper[] = { '+', '-', '*', '/', '%', '(', ')', '^' };
                                              int sz = sizeof oper / sizeof *oper;
                                              int i;
                                              
                                              for (i = 0; i < sz; i++)
                                                if (c == oper[i])
                                                  return 1;
                                              return 0;
                                            }
                                            
                                            int setPrio(int op) {
                                              int i, sz;
                                              struct {
                                                char op;
                                                int val;
                                              } equ[] = {
                                                { '(', 0 },
                                                { '=', 1 },
                                                { '+', 2 },
                                                { '-', 2 },
                                                { '*', 3 },
                                                { '/', 3 },
                                                { '%', 3 },
                                                { '^', 4 }
                                              };
                                              
                                              sz = sizeof equ / sizeof *equ;
                                              for (i = 0; i < sz; i++)
                                                if (op == equ[i].op)
                                                  return equ[i].val;
                                              
                                              /* Unknown operator */
                                              return -1;
                                            }
                                            
                                            /* '=' < '(' < '+' < '-' < '*' < '/' < '^' */
                                            int priority(int op1, int op2) {
                                              if (op1 == '^' && op2 == '^')
                                                return 1;
                                              op1 = setPrio(op1);
                                              op2 = setPrio(op2);
                                              return op1 > op2;
                                            }
                                            
                                            int handleOper(char * src, char ** dst, estate * state, n_stack * st) {
                                              type_u v;
                                              int type;
                                              int tmp;
                                              
                                              if (*src == '(') {
                                                if ((state->current == C_OPER && state->val_cur_op == ')') ||
                                                    state->current == C_NUM) {
                                                  v.val = '*';
                                                  CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                }
                                                
                                                v.val = *src;
                                                CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                
                                                state->affect = 1;
                                                state->current = C_OPER;
                                                state->val_cur_op = '(';
                                                src++;
                                                
                                                convertNPI(src, &src, st, state);
                                                if (error != E_OK)
                                                  return -1;
                                                
                                                src = skipSpace(src);
                                                if (*src != ')') {
                                                  calcSetError(E_BRAC);
                                                  return -1;
                                                }
                                                src++;
                                                
                                                /* Si c'est un parenthèse fermante on dépop toute la stack 2
                                                 * jusqu'à la parenthèse */
                                                tmp = st->st[1].i;
                                                while (st->st[1].st[tmp-1][0] != '(') {
                                                  v = popStack(&st->st[1], &type);
                                                  if (type == C_NOOP)
                                                    return -1;
                                                  CHECK_PUSH_STACK(&st->st[0], v, type);
                                                  tmp = st->st[1].i;
                                                }
                                                /* Bracket */
                                                popStack(&st->st[1], &type);
                                              }
                                              else {
                                                if (state->current == C_OPER && state->val_cur_op != '(' &&
                                                    state->val_cur_op != ')') {
                                                  calcSetError(E_OPER);
                                                  return -1;
                                                }
                                                
                                                /* On ajoute sur la stack 2 si elle est vide, sinon on regarde
                                                 * la priorité des opérateurs.
                                                 * Si l'opérateur en cours a une prio plus importante, on le stocke,
                                                 * sinon on depop sur la stack 1 */
                                                tmp = st->st[1].i;
                                                if (st->st[1].i == 0 || priority(*src, st->st[1].st[tmp-1][0]) == 1) {
                                                  v.val = *src;
                                                  CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                }
                                                else {
                                                  /* Tant que la prio de l'op en cours est inférieure à celle
                                                   * sur la stack, on dépile sur la stack 1 */
                                                  while (priority(*src, st->st[1].st[tmp-1][0]) != 1) {
                                                    v = popStack(&st->st[1], &type);
                                                    if (type == C_NOOP)
                                                      return -1;
                                                    CHECK_PUSH_STACK(&st->st[0], v, type);
                                                    tmp = st->st[1].i;
                                                  }
                                                  /* On mets l'op sur la stack 2 */
                                                  v.val = *src;
                                                  CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                }
                                                
                                                state->current = C_OPER;
                                                state->val_cur_op = *src;
                                                src++;
                                              }
                                              
                                              if (dst != NULL)
                                                *dst = src;
                                              return 0;
                                            }
                                            
                                            #pragma mark Calc
                                            /* >> Fonctions de gestion et de calcul << */
                                            
                                            int convertNPI(char * src, char ** dst, n_stack * st, estate * state) {
                                              type_u v;
                                              
                                              state->sig = 1;
                                              
                                              while (*src) {
                                                src = skipSpace(src);
                                                
                                                /* Variable */
                                                if (isalpha(*src)) {
                                                  if (handleVar(src, &src, state, st) < 0)
                                                    return -1;
                                                }
                                                else if (*src == '-') {
                                                  src++;
                                                  src = skipSpace(src);
                                                  
                                                  if (state->current == C_NOOP || state->current == C_AFFECT ||
                                                      (state->current == C_OPER && state->val_cur_op == '(')) {
                                                    v.val = '*';
                                                    CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                    v.val = -1;
                                                    CHECK_PUSH_STACK(&st->st[0], v, C_NUM);
                                                    
                                                    state->sig = -1;
                                                  }
                                                  else if ((state->current == C_OPER && state->val_cur_op == ')') ||
                                                           state->current == C_FUNC || state->current == C_NUM) {
                                                    char tmp_s[2] = "-";
                                                    
                                                    if (handleOper(tmp_s, NULL, state, st) < 0)
                                                      return -1;
                                                  }
                                                  else {
                                                    calcSetError(E_OPER);
                                                    return -1;
                                                  }
                                                }
                                                else if (isdigit(*src)) {
                                                  int n;
                                                  
                                                  if (state->current == C_NUM) {
                                                    calcSetError(E_NUMB);
                                                    return -1;
                                                  }
                                                  else if (state->current == C_OPER && state->val_cur_op == ')') {
                                                    v.val = '*';
                                                    CHECK_PUSH_STACK(&st->st[1], v, C_OPER);
                                                  }
                                                  
                                                  errno = 0;
                                                  n = strtol(src, &src, 10);
                                                  if (errno) {
                                                    perror("");
                                                    return -1;
                                                  }
                                                  
                                                  v.val = n;
                                                  CHECK_PUSH_STACK(&st->st[0], v, C_NUM);
                                                  state->current = C_NUM;
                                                }
                                                else if (isOper(*src)) {
                                                  if (*src == ')') {
                                                    state->current = C_OPER;
                                                    state->val_cur_op = *src;
                                                    break;
                                                  }
                                                  if (handleOper(src, &src, state, st) < 0)
                                                    return -1;
                                                }
                                                else if (*src == ',') {
                                                  if (state->func) {
                                                    state->current = C_OPER;
                                                    state->val_cur_op = *src;
                                                    break;
                                                  }
                                                  else {
                                                    calcSetError(E_OPCO);
                                                    return -1;
                                                  }
                                                }
                                                else {
                                                  calcSetError(E_UERR);
                                                  return -1;
                                                }
                                              }
                                              
                                              *dst = src;
                                              return 0;
                                            }
                                            
                                            int calcNPI(stack * st) {
                                              type_u v;
                                              int n1, n2, op;
                                              int i;
                                              
                                              i = st->i;
                                              
                                              if (error)
                                                return -1;
                                              else if (i == 0) {
                                                calcSetError(E_OPAG);
                                                return -1;
                                              }
                                              else if (st->st[i-1][1] == C_NUM) {
                                                CHECK_POP_STACK(v, st);
                                                return v.val;
                                              }
                                              else if (st->st[i-1][1] == C_AFFECT) {
                                                llist_val lv;
                                                
                                                strcpy(lv.name, st->name[i-1]);
                                                CHECK_POP_STACK(v, st);
                                                n1 = calcNPI(st);
                                                if (error)
                                                  return -1;
                                                
                                                lv.val = n1;
                                                if (pushLlist(&list_g, &lv) == NULL)
                                                  return -1;
                                                if (list_g.add == NULL)
                                                  list_g.add = list_g.end;
                                                return n1;
                                              }
                                              else if (st->st[i-1][1] == C_FUNC) {
                                                int tmp;
                                                funcs * f;
                                                
                                                tmp = st->st[i-1][0];
                                                f = &func_call[tmp];
                                                CHECK_POP_STACK(v, st);
                                                if (f->args == 1) {
                                                  n1 = calcNPI(st);
                                                  return f1[tmp](n1);;
                                                }
                                                else if (f->args == 2) {
                                                  n1 = calcNPI(st);
                                                  n2 = calcNPI(st);
                                                  return f2[tmp-N_FUNC_1_ARG](n2, n1);
                                                }
                                              }
                                              else if (st->st[i-1][1] == C_OPER) {
                                                op = st->st[i-1][0];
                                                CHECK_POP_STACK(v, st);
                                                n1 = calcNPI(st);
                                                n2 = calcNPI(st);
                                                
                                                if (op == '+')
                                                  return n2 + n1;
                                                else if (op == '-')
                                                  return n2 - n1;
                                                else if (op == '*')
                                                  return n2 * n1;
                                                else if (op == '%') {
                                                  if (n1 == 0) {
                                                    calcSetError(E_DIV0);
                                                    return -1;
                                                  }
                                                  return n2 % n1;
                                                }
                                                else if (op == '/') {
                                                  if (n1 == 0) {
                                                    calcSetError(E_DIV0);
                                                    return -1;
                                                  }
                                                  return n2 / n1;
                                                }
                                                else if (op == '^')
                                                  return pow(n2, n1);
                                                else {
                                                  /* Should never happen... */
                                                  calcSetError(E_OPUK);
                                                  return -1;
                                                }
                                              }
                                              else {
                                                calcSetError(E_UERR);
                                                return -1;
                                              }
                                              
                                              return -1;
                                            }
                                            
                                            int calcExp(char * s) {
                                              int n;
                                              n_stack st;
                                              estate state;
                                              
                                              state.affect = 1;
                                              state.current = 0;
                                              state.sig = 1;
                                              state.val_cur_op = 0;
                                              state.func = 0;
                                              
                                              s = skipSpace(s);
                                              if (*s == '\0')
                                                return 0;
                                              
                                              memset(&st, 0, sizeof st);
                                              
                                              if (convertNPI(s, &s, &st, &state) < 0) {
                                                return -1;
                                              }
                                              if (!error && *s != '\0') {
                                                calcSetError(E_UERR);
                                                return -1;
                                              }
                                              if (popAllStack(&st) < 0)
                                                return -1;
                                              
                                              n = calcNPI(&st.st[0]);
                                              if (error)
                                                return -1;
                                              
                                              printf("-: %d\n", n);
                                              while (list_g.add != NULL) {
                                                printf("%s = %d\n", list_g.add->name, list_g.add->val);
                                                list_g.add = list_g.add->nxt;
                                              }
                                              list_g.ans->val = n;
                                              
                                              return 0;
                                            }
                                            
                                            void printHelp(void) {
                                              printf("q, quit   :> Quitter\n");
                                              printf("c, clear  :> Supprimer les variables\n");
                                              printf("h, help   :> Affiche l'aide\n");
                                            }
                                            
                                            int evaluate(char * s) {
                                              int ret;
                                              
                                              delEnter(s);
                                              s = skipSpace(s);
                                              
                                              if (strcmp(s, "quit") == 0 || strcmp(s, "q") == 0)
                                                ret = 1;
                                              else if (strcmp(s, "clear") == 0 || strcmp(s, "c") == 0) {
                                                list_g.ans->val = 0;
                                                while (popLlist(&list_g) != NULL)
                                                  ;
                                                ret = 0;
                                              }
                                              else if (strcmp(s, "help") == 0 || strcmp(s, "h") == 0) {
                                                printHelp();
                                              }
                                              else if (strcmp(s, "ans") == 0) {
                                                printf("ans = %d\n", list_g.ans->val);
                                                ret = 0;
                                              }
                                              else {
                                                ret = calcExp(s);
                                              }
                                              
                                              return ret;
                                            }
                                            
                                            int prompt(void) {
                                              int tmp;
                                              int done = 0;
                                              char s[N_MAX] = "";
                                              
                                              while (!done) {
                                                printf(">>> ");
                                                if (fgets(s, N_MAX, stdin) == NULL) {
                                                  perror("Erreur fgets");
                                                  continue;
                                                }
                                                tmp = evaluate(s);
                                                
                                                if (tmp < 0 && error != E_OK) {
                                                  printError(NULL);
                                                  calcSetError(E_OK);
                                                }
                                                else if (tmp > 0)
                                                  done = 1;
                                              }
                                              
                                              return 0;
                                            }
                                            
                                            void release_llist(void) {
                                              free(list_g.ans);
                                              while (list_g.begin != NULL)
                                                popLlist(&list_g);
                                            }
                                            
                                            int init(void) {
                                              list_g.ans = malloc(sizeof *list_g.ans);
                                              
                                              if (list_g.ans == NULL) {
                                                calcSetError(E_MALC);
                                                return -1;
                                              }
                                              
                                              list_g.ans->nxt = NULL;
                                              list_g.ans->val = 0;
                                              strcpy(list_g.ans->name, "ans");
                                              
                                              list_g.begin = NULL;
                                              list_g.end = NULL;
                                              list_g.add = NULL;
                                              
                                              atexit(release_llist);
                                              
                                              calcSetError(E_OK);
                                              
                                              return 0;
                                            }
                                            
                                            int main(void) {
                                              if (init() < 0) {
                                                printError(NULL);
                                                return EXIT_FAILURE;
                                              }
                                              return prompt() ? EXIT_FAILURE : EXIT_SUCCESS;
                                            }
                                            

                                            >>> (1+2)-(3*4)(5*6)
                                            -: -357
                                            >>> -1*4+2
                                            -: -2
                                            >>> pow(5,3)
                                            -: 125
                                            >>> 5^2^2
                                            -: 625
                                            >>> 5^2^2%4
                                            -: 1
                                            >>> q

                                            Edit: Rajout d'une erreur. :)
                                            Edit2: Modification suite aux remarques. :)
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              15 octobre 2010 à 22:21:37

                                              Bah moi je dit respect! :-°
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Zeste de Savoir, le site qui en a dans le citron !
                                                16 octobre 2010 à 11:45:34

                                                Très beau code ! Un poil compliqué (?) mais en tout cas chapeau !
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  16 octobre 2010 à 11:56:11

                                                  Je viens de voir que dans ton code tu ne considère pas avec la même priorité les opérateurs + et - ni * et /. Alors qu'ils sont sensé l'être. (Même le % à un niveau de priorité égal au * et au / si je ne dis pas de bêtises)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    16 octobre 2010 à 12:08:10

                                                    Citation : Tosh

                                                    Je viens de voir que dans ton code tu ne considère pas avec la même priorité les opérateurs + et - ni * et /. Alors qu'ils sont sensé l'être. (Même le % à un niveau de priorité égal au * et au / si je ne dis pas de bêtises)


                                                    Ca ne pose pas de problème, si?

                                                    Par exemple
                                                    5 - 7 + 2
                                                    si on évalue 7 + 2 en premier, ça n'a pas d'importance, si?

                                                    Je n'arrive pas à trouver de cas problématiques. :-°

                                                    edit: c'est l'inverse en fait, puisque pouet donne une priorité supérieure au -.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Zeste de Savoir, le site qui en a dans le citron !
                                                      16 octobre 2010 à 12:15:07

                                                      Essaye 9/2*7 :) .

                                                      si tu fais 9/(2*7) c'est différent de (9/2)*7.

                                                      EDIT : Il y a aussi un petit soucis sur le ans on dirait.

                                                      >>> ans
                                                      ans = 16
                                                      >>> ans+7
                                                      Variable does not exist
                                                      >>>
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        16 octobre 2010 à 13:03:11

                                                        Ca change pas grand chose (rien?). Mais bon, je l'ai modifié comme ça tout le monde est content. :p
                                                        ans fix'd. ;)
                                                        Si ya pas de parenthèses, c'est évaluation de gauche à droite. :)
                                                        9/2*7 = 28. :-°
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          16 octobre 2010 à 20:58:52

                                                          Citation : GurneyH


                                                          Par exemple
                                                          5 - 7 + 2
                                                          si on évalue 7 + 2 en premier, ça n'a pas d'importance, si?


                                                          ? o_O

                                                          (5-7)+2 = 0
                                                          5-(7+2) = -4

                                                          L'ensemble des réels est laxiste mais pas à ce point-là :lol:
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          zCalc

                                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                          • Editeur
                                                          • Markdown