Projet de calculatrice simple en langage C
Projet de calculatrice simple en langage C
Cet article propose en détaille un projet de calculatrice simple en langage C.
Vous pourrez télécharger le fichier au format zip il contient le code sources complet.
Extrait du code source :
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#define cte 310
#define expr 96100
typedef enum {true=1,false=0} boolean;
typedef struct liste
{
char membre[7];
struct liste *suivant;
struct liste *tete;
struct liste *queue;
int nbrelem;
}liste;
char testString[expr];
int lire(char *chaine, int longueur);
void viderBuffer();
char *space(char *chaine);
char *plusoumoins(char *chaine);
int verification(char *chaine);
double *addition(double x, double y);
double *soustraction(double a,double b);
double *multiplication(double x, double y);
double *division(double x, double y);
double *puissance(double x, double y);
double *factorielle(double x);
int priority(char op);
void vidertmpstring(char *tmpstring);
void videroperateur(char tmp[cte][cte]);
liste *creer_liste();
boolean liste_vide(liste* l);
void ajouter_en_queue(liste *l,char *membre);
char *retirer_en_queue(liste *l);
void empiler(char expression[cte][cte],int *k,char *membre,liste *lst);
void maPile(char* chaine,liste *lst);
double* evaluer(char expression[cte][cte]);
void decallage_binaire(char expression[cte][cte],int *i);
void decallage_unaire(char expression[cte][cte],int *i);
/** PROGRAMME PRINCIPAL **/
int main()
{
int feu;
liste *lst;
while(1)
{
do
{
printf("\n\n\t Entrer Votre expression \n\n\t ");
feu=lire(testString,expr);
if(feu==0)
{
printf("\n\t N'oubliez pas : Nous sommes en C ; ");
printf("\n\t Un nombre reel de type double doit avoir au plus 310 caracteres. ");
printf("\n\n\t");
system("pause");
system("cls");
}
} while(feu!=1);
feu=0;
strcpy(testString,space(testString));
strcpy(testString,plusoumoins(testString));
if(verification(testString))
{
lst=creer_liste();
if(lst==NULL)
{
perror("\n\t Erreur lors de la creation de la liste. ");
printf("\n\t Appuyez sur une touche pour quitter le programme. ");
getch();
exit(EXIT_FAILURE);
}
maPile(testString,lst);
}
}
return 0;
}
PREMIERE ETAPE
/** Prendre la chaîne de caractère et supprimer les espaces **/
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
int lire(char *chaine, int longueur)
{
char *positionEntree = NULL;
if (fgets(chaine, longueur, stdin) != NULL) /** Si la lecture se passe bien, on remplace le '\n' par le '\0', on retourne le code de succès : 1 et on sort de la fonction. **/
{
positionEntree = strchr(chaine, '\n');
if (positionEntree != NULL)
{
*positionEntree = '\0'; /** C'est ici qu'on remplace le '\n' par le '\0' **/
}
else /** Si la lecture c'est faite, et qu'on ne trouve pas le '\n', il y'a une erreur( du au fait que la chaine était trop longue pour nous )
on vide le flux d'entrée standard stdin et on retourne le code d'erreur 0. **/
{
printf("\n\t Votre expression est trop longue ");
viderBuffer();
return 0;
}
return 1; /** Si on n'arrive ici, c'est que tout c'est bien passée et on retourne le code de succèss 1. **/
}
else /** Si pour je ne sais quel raison la lecture c'est la lecture n'a pas pu être faite, il y'a erreur et on retourne le code d'erreur 0. **/
{
viderBuffer();
return 0;
}
}
char *space(char *chaine)
{
char *ptr;
int i=0;
for(i=0;chaine[i]!='\0';i++)
{
if(isspace(chaine[i]))
{
ptr=&chaine[i];
strcpy(ptr,ptr+1);
--i;
}
}
return chaine;
}
/*** Reprendre la chaîne de caractère sans espace et arranger les + et - qui se suivent. **/
/** Soit à dire que - * - == +, + * + == +, - * + == -, + * - == - **/
char *plusoumoins(char *chaine)
{
char *ptr;
int nbredeplus,nbredemoins;
int longueur;
int i,feu,findesplusoumoins,position;
i=0;
feu=0;
nbredeplus=nbredemoins=findesplusoumoins=position=longueur=0;
for(i=0;chaine[i]!='\0';i++)
{
if(chaine[i]=='+'||chaine[i]=='-')
{
position=i;
if(chaine[i]=='+')
nbredeplus++;
if(chaine[i]=='-')
nbredemoins++;
while(chaine[i+1]=='+'||chaine[i+1]=='-')
{
if(chaine[i+1]=='+')
nbredeplus++;
if(chaine[i+1]=='-')
nbredemoins++;
i++;
feu=1;
}
}
if(feu==1)
{
nbredemoins%=2;
nbredeplus%=2;
findesplusoumoins=i;
longueur=findesplusoumoins-position+1;
i-=longueur;
ptr=&chaine[position];
if( nbredemoins==0 && (nbredeplus==0||nbredeplus==1))
{
*ptr='+';
strcpy(ptr+1,ptr+longueur);
}
if( nbredemoins==1 && (nbredeplus==0||nbredeplus==1))
{
*ptr='-';
strcpy(ptr+1,ptr+longueur);
}
}
nbredemoins=nbredeplus=0;
feu=0;
}
return chaine;
}
DEUXIEME ETAPE : VERIFIER SI LA CHAÎNE QU'ON A FABRIQUEE EST UNE EXPRESSION MATHEMATIQUE BIEN FORMEE
int verification(char *chaine)
{
int i,j,feu,parenthese;
double resultat;
char *errcode=NULL;
char *ptr,*ptr1;
char *tmpstring;
/** Déclaration des variables globales */
char fonction[36][8] = {"sin(", "cos(", "tan(","sinh(","cosh(","tanh(","acos(","asin(","atan(","asinh(","acosh(","atanh(","ln(", "log(","sqrt(", "exp(","mod(",
"e","E","sin", "cos", "tan","sinh","cosh","tanh","acos","asin","atan","asinh","acosh","atanh","ln", "log","sqrt", "exp","mod"};
/** On va s'assurer que le nombre de parenthèse ouvrante '(' est égale au nombre de paranthèse fermente ')' et qu'elles sont dans le bon sens
qu'on n'a pas par exemple une expression du genre )30+252(. On vérifie par la même occasion que les parenthèses sont non vide.
C'est parce que les parenthèses on la plus haute priorité **/
/** Comptons maintenant le nombre de parenthèse ouvrante et le nombre de parenthèse fermente et comparons. S'il ne sont pas égaux, il y'a erreur. **/
for ( i=0, parenthese=0; chaine[i]!='\0'; i++ )
{
if ( chaine[i]=='(' )
parenthese++;
else if ( chaine[i]==')' )
parenthese--;
}
if ( parenthese!=0 ) /** Si le nombre de '(' != du nombre de ')' alors on retourne notre code d'erreur : 0 */
{
printf("\n\t Syntax ERROR 1 ");
return 0;
}
/** Le test sur le nombre de parenthèse est terminer**/
/** Testons le sens des parenthèses et les parenthèses vide du genre 2+() est terminé. **/
parenthese=0;i=0,j=0;
ptr=calloc(sizeof(ptr),strlen(chaine)+1);
if(ptr!=NULL)
strcpy(ptr,chaine);
else
{
printf("\n\t Erreur lors de l'allocation memoire. ");
exit(0);
}
while(strchr(ptr,')'))
{
ptr1=strchr(ptr,')');
j=ptr1-ptr;
for(i=0;i<j-1;i++)
{
if(ptr[i]=='(')
{
parenthese++;
break;
}
}
if(parenthese==0)
{
printf("\n\t Syntax ERROR 2 ");
free(ptr);
return 0;
}
parenthese=0;
strcpy(ptr1,ptr1+1);
}
/** le test sur le sens des parenthèses et les parenthèses vide du genre 2+() est terminé. **/
/** On remplace tous les E par e et toutes les virgules française ',' par les virgules anglaise '.' **/
for ( i=0; chaine[i]!='\0'; i++ )