Ben voila, c'est un programme qui traite une expression du style : ((5+4)*(7-2)). Ce programme ne fait pas que calculer les résultats il affiche aussi les étapes intermédiaires. en gros pour l'exemple précédent ça donne ça :
((5+4)*(7-2))
(9*(7-2))
(9*5)
45
pour faire cela j'ai du redéfinir quelques fonctions:
Compare_Char(char *s, char *t) // compare 2 chaines (version adaptée à mon programme il ne compare pas vraiment toute la chaine mais 1 partie seulement)
int Longueur(char *s); // Longueur d'une chaine de Char
int Longueur(int Valeur); // Longueur d'un Int
- Ent_To_Char(int Valeur, char *Entier); // Ent => Char*
Char_To_Ent(char *Expr); // Char* => Ent
- Ajouter(char *s, char *t);
Source / Exemple :
#include "stdio.h"
#include <stdlib.h>
#define TAILLE_MAX 256 // Taille maximal pour le tableau de la formule
#define TABLEAU_MAX 50
#define Nb_Operateur 5 // Nombre d'operateur reconnue par le programme
/*----------------------------------------
Definition des fonctions de ce module
----------------------------------------*/
int Compare_Char(char *s, char *t); // Fonction non general remanie pour le programme
int Longueur(char *s);
int Longueur(int Valeur);
char *Ent_To_Char(int Valeur, char *Entier);
int Char_To_Ent(char *Expr);
char *Ajouter(char *s, char *t);
bool Parentheses(char *Chaine);
char *Analyse_Formule(char *Formule);
char *Analyse_Expression(char *Expr);
/*---------------------
Debut du programme
----------------------*/
int main(int argc, char* argv[])
{
int i;
char *Expression;
if (argc != 2)
printf("Tu doit rentrer une formule de Maths\n");
else
{
Expression = Analyse_Formule(argv[1]);
for(i = 0; i < Longueur(Expression); i++)
printf("%c", Expression[i]);
free(Expression);
}
return 0;
}
/*-----------------------
Compare deux chaine
------------------------*/
int Compare_Char(char *s, char *t)
{
for(; *s == *t; s++, t++)
if(*s == ':')
return 0;
return (*s - *t);
}
/*------------------------------------
Calcule la longueur de la chaine
------------------------------------*/
int Longueur(char *s)
{
char *p = s;
while (*p != '\0')
p++;
return (p - s);
}
/*-----------------------------------
Calcule la longueur d'un entier
-----------------------------------*/
int Longueur(int Valeur)
{
int Retour = 0;
if(Valeur < 0)
{
Retour++;
Valeur = -1 * Valeur;
}
while(Valeur !=0)
{
Retour++;
Valeur = Valeur / 10;
}
return Retour;
}
/*------------------------------------------------
Transforme une chaine de caractere en entier
------------------------------------------------*/
int Char_To_Ent(char *Expr)
{
int i, n, Signe;
for(i = 0; Expr[i] == ' '; i++)
;
Signe = (Expr[i] == '-')? -1 : 1;
if (Expr[i] == '+' || Expr[i] == '-')
i++;
for(n = 0; (Expr[i] <= '9' && Expr[i] >= '0'); i++)
n= 10 * n + (Expr[i] - '0');
return (Signe * n);
}
/*---------------------------------------------------
Transforme un entier en une chaine de caractere
---------------------------------------------------*/
char *Ent_To_Char(int Valeur, char *Entier)
{
int Lng = Longueur(Valeur);
int tmp = 1;
if(Valeur == 0)
Entier[0] = '0';
else
{
if (Valeur < 0)
{
Entier[0] = '-';
Valeur = -1 * Valeur;
}
while(Valeur !=0)
{
Entier[Lng - tmp] = '0' + (Valeur % 10);
Valeur = Valeur / 10;
tmp++;
}
}
Entier[Lng] = '\0';
return Entier;
}
/*----------------
Ajoute t à s
----------------*/
char *Ajouter(char *s, char *t)
{
int i = 0;
int j = 0;
char *Ch = (char*)malloc(sizeof(char) * TAILLE_MAX);
while(s[i] != '\0')
Ch[i] = s[i++];
while(t[j] != '\0')
Ch[i++] = t[j++];
Ch[i] = '\0';
return Ch;
}
/*-------------------------------------------------------------
Verifie la conformite des parentheses
-------------------------------------------------------------*/
bool Parentheses(char *Chaine)
{
int Ouverte, Ferme, i, Nbr;
Ouverte = 0;
Ferme = 0;
Nbr = Longueur(Chaine);
for(i = 0; i < Nbr; i++)
{
if ((Chaine[i] == '('))
Ouverte++;
else
if ((Chaine[i] == ')'))
{
Ferme++;
if (Ouverte < Ferme)
return false;
}
}
if (Ouverte != Ferme)
return false;
else
return true;
}
/*-------------------------------------------------------------
Fonction recursive qui analyse la structure de la formule
-------------------------------------------------------------*/
char *Analyse_Formule(char *Formule)
{
int i, j, Lng;
int Nbr_Parenthese, Parenthese_O, Parenthese_F, Taille_Expression;
char *Ch = (char*)malloc(sizeof(char) * TAILLE_MAX);
char R[26] = "impossible de calculer : ";
char *Chaine = (char*)malloc(sizeof(char) * TAILLE_MAX);
bool Suite = true;
Nbr_Parenthese = 0;
Parenthese_O = -1;
Parenthese_F = -1;
Taille_Expression = Longueur(Formule);
if (Parentheses(Formule) == false) // Traitement de l'erreur
{
for(i = 0; i < 26; i++)
Chaine[i] = R[i];
Chaine[25] = '1';
Chaine[26] = '\n';
Chaine[27] = '\0';
free(Ch);
return Chaine;
}
for(i = 0; (i < Taille_Expression) && Suite; i++)
{
switch(Formule[i])
{
case '(':
Nbr_Parenthese++;
Parenthese_O = i;
break;
case ')':
Parenthese_F = i;
Suite = false;
break;
default:
break;
}
}
for(i = 0; i < Parenthese_O; i++) // Rempli le debut de l'expressio suivante
Chaine[i] = Formule[i];
j = 0;
for(i = (Parenthese_O + 1); i < Parenthese_F; i++)
Ch[j++] = Formule[i];
Ch[j]='\0';
Ch = Analyse_Expression(Ch); // Calcule de l'expression entre parentheses
if (Ch[0] == '@') // Traitement de l'erreur
{
for(i = 0; i < 26; i++)
Chaine[i] = R[i];
Chaine[25] = Ch[1]; // Traitement du type d'erreur
Chaine[26] = '\n';
Chaine[27] = '\0';
free(Ch);
return Chaine;
}
j = Parenthese_O;
Lng = Longueur(Ch);
for(i = 0; i < Lng; i++) // Rempli l'expression avec le resultat de l'expression entre parentheses
Chaine[j++] = Ch[i];
for(i = (Parenthese_F + 1); i <= Taille_Expression; i++) // Rempli l'expression avec le reste de l'expression de depart
Chaine[j++] = Formule[i];
free(Ch);
if (Nbr_Parenthese < 2)
{
Formule = Ajouter(Formule, "\n\0");
Chaine = Ajouter(Formule, Chaine);
return Chaine;
}
else
{
Formule = Ajouter(Formule, "\n\0");
Chaine = Analyse_Formule(Chaine);
if (Compare_Char(Chaine, R) == 0)
for(i = 0; i <= Longueur(Chaine); i++)
Formule[i] = Chaine[i];
else
{
Formule = Ajouter(Formule, Chaine);
Formule = Ajouter(Formule, "\n\0");
}
free(Chaine);
return Formule;
}
}
/*--------------------------------------
Fonction qui calcul une expression
---------------------------------------*/
char *Analyse_Expression(char *Expr)
{
int Valeurs[TABLEAU_MAX];
char Op[Nb_Operateur + 1] = "*/%+-";
char Operateurs[TABLEAU_MAX];
int i, j, k;
int Val, Lng_Val, Lng_Expr;
int Indexe_Valeurs = 0;
int Indexe_Operateurs = 0;
Val = Char_To_Ent(Expr);
Valeurs[Indexe_Valeurs++] = Val;
Lng_Val = Longueur(Val);
Lng_Expr = Longueur(Expr);
j = 0;
for(i = (Lng_Val); i <= Lng_Expr; i++)
Expr[j++] = Expr[i];
Lng_Expr -= Lng_Val;
while(Lng_Expr > 0)
{
Operateurs[Indexe_Operateurs++] = Expr[0];
for(i = 1; i <= Lng_Expr; i++)
Expr[i - 1] = Expr[i];
Val = Char_To_Ent(Expr);
Valeurs[Indexe_Valeurs++] = Val;
Lng_Val = Longueur(Val);
j = 0;
for(i = (Lng_Val); i <= Lng_Expr; i++)
Expr[j++] = Expr[i];
Lng_Expr = Longueur(Expr);
}
Operateurs[Indexe_Operateurs] = Expr['\0'];
for(i = 0; i < Nb_Operateur; i++)
for(j = 0; j < Indexe_Operateurs; j++)
{
if(Operateurs[j] == Op[i])
{
switch(Operateurs[j])
{
case '*':
Val = Valeurs[j] * Valeurs[j + 1];
break;
case '/':
if (Valeurs[j + 1] == 0)
{
char *Retour = (char*)malloc(sizeof(char) * TAILLE_MAX);
Retour[0] = '@';
Retour[1] = '0';
return Retour;
}
else
Val = Valeurs[j] / Valeurs[j + 1];
break;
case '%':
Val = Valeurs[j] % Valeurs[j + 1];
break;
case '+':
Val = Valeurs[j] + Valeurs[j + 1];
break;
case '-':
Val = Valeurs[j] - Valeurs[j + 1];
break;
}
for(k = j; k < Indexe_Operateurs - 1; k++)
Operateurs[k] = Operateurs[k + 1];
Indexe_Operateurs--;
Valeurs[j] = Val;
for(k = (j + 1); k < Indexe_Valeurs - 1; k++)
Valeurs[k] = Valeurs[k + 1];
Indexe_Valeurs = Indexe_Valeurs--;
j--; // Pour ne pas loupe d'opperateur
}
}
return Ent_To_Char(Val, Expr);
}
Conclusion :
Pour le moment le programme ne reconnait pas beaucoups d'opérateurs (*/%+-) mais je vais le continuer et il devrait aussi comprendre les flotant (pour le moment que les Int) et quelques fonctions de base Sin, Cos, .....
Je sais le code est un peut bizarre, alors si vous avez des problèmes à le comprendre ou des remarques a faire JE SUIS LA
(enfin normalement)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.