|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
VRAI CALCULETTE
Information sur la source
Description
petite calculette effectuants des operation du genre: (2+3)(4/(10/5)p-8)*-2u2. (elle ne gere pas encore les fonction cos,sin...ni les racines carres Bug connu: petit risque de legere erreur si on utilise des nombre trop petit (exxuser moi pour les fautes d'orthographes
Source
- //dans le fichier calculette.cpp
- #include <iostream.h>
- #include <stdlib.h>
- #include <conio.h>
- #include "fcalculette.h"
-
-
- int main(void)
- {
- gestion a;
- char entre[300];
- do
- {
- cout<<"entrez une operation :"<<endl;
- cin>>entre;
- }while (a.cal(entre));
- system("pause");
- return 0;
- }
-
- //dans le fichier fcalculette.h
- #include <ctype.h>
- #include <stdio.h>
-
-
- /*************************************************************************************************
- fonction :
- **************************************************************************************************/
-
- bool transfo(double don,char *tran,int taille) //transforme un double en chaine de caractere.
- {
- double nb=don;
- int inc=0,i=0,pui=0;
- if(nb<0)
- {
- *tran='-';
- nb*=-1;
- i++;
- }
- while(nb>=1) {nb/=10;inc++;}
- int rep=0,chi=0;
- for(;rep!=5 && i<taille;i++,inc--)
- {
- nb*=10; // j'ai un probleme avec cette methode un double peut prendre
- if(inc==0) *(tran+i++)='.'; // des valeur bizarre du genre 123.0000000000000000354454343...
- if(chi==(int)(nb) && inc<0) rep++; // au lieux de 123 j'aimerai savoir ou es le bug car ca peut
- else {chi=(int)(nb);rep=0;} // faire bizzare dans le programme et introduire une petite
- *(tran+i)=(int)(nb)+48; // erreur.
- nb-=(int)(nb);
- }
- if(rep==5) i-=4;
- if(i==taille)
- {
- *(tran+i-1)='\0';
- return false;
- }
-
- *(tran+i)='\0';
- return true;
- }
-
- double exp(double nb,int ex) //pour les calcules avec exposants
- {
- double res=nb;
- if(!ex)
- {
- if(nb>=0) res=1;
- else res=-1;
- ex=1;
- }
- while(ex!=1 && ex!=-1)
- {
- if(ex>0) ex--;
- else ex++;
- res*=nb;
- }
- if(ex==-1) res=1/res;
- return res;
- }
-
- double cherchenb(const char *ope,int &cur) //transforme une chaine de caractere en nombre
- {
- double nobe=0,nobd=0;
- int dec=-1,pos=0;
- for(;isdigit(*(ope+pos)) || (*(ope+pos)=='.' && dec==-1);pos++)
- {
- if(*(ope+pos)=='.') dec=0;
- else if(dec==-1)
- {
- nobe*=10;
- nobe+=*(ope+pos)-48;
- }
- else
- {
- nobd*=10;
- nobd+=*(ope+pos)-48;
- dec++;
- }
- }
- cur+=pos;
- if(nobd==0) return nobe;
- else return nobe+(nobd/(exp(10,dec)));
- }
-
-
- /*************************************************************************************************
- class mere:
- **************************************************************************************************/
-
- class calcul
- {
- double res,*temp;
- int taille,i;
- char *opera;
- bool op(const char &);
- int chsigne(void);
-
- protected: //protected pour que la classe fille puisse l'utiliser.
- int err;
- void error(int,int);
- double resultat(void);
-
- public:
- calcul(void);
- ~calcul(void);
- void affiche(void);
- void reinit(void);
- bool effectue(const char *);
-
- };
-
-
- /*************************************************************************************************
- definition des fonctions de la class mere:
- **************************************************************************************************/
-
-
- calcul::calcul(void)
- {
- res=0;temp=0;
- err=0;
- taille=0;i=0;
- temp=new double[2];
- opera=NULL;
- }
-
- calcul::~calcul(void)
- {
- delete [] opera;
- delete [] temp;
- }
-
- void calcul::reinit(void)
- {
- delete [] opera;
- res=0;err=0;i=0;
- taille=0;
- }
-
- void calcul::error(int ce,int pos=0) //gestions des erreurs dans l'operation rentré avec affichage de l'emplacement de celle ci.
- {
- err=1;
- switch (ce)
- {
- case 1:
- {
- cout<<"erreur chaine de calcul vide."<<endl;
- break;
- }
- case 2:
- {
- cout<<"erreur de syntaxe position:"<<pos<<endl;
- for(int j=0;j<taille;j++) cout<<*(opera+j);
- cout<<endl;
- for(int j=0;j<(pos-1);j++) cout<<" ";
- cout<<"|"<<endl;
- break;
- }
- case 3:
- {
- cout<<"ce programme ne gere pas les exposants decimals."<<endl;
- for(int j=0;j<taille;j++) cout<<*(opera+j);
- cout<<endl;
- for(int j=0;j<(pos-1);j++) cout<<" ";
- cout<<"|"<<endl;
- break;
- }
- case 4:
- {
- cout<<"erreur: parentheses \"(\" manquante."<<endl;
- break;
- }
- case 5:
- {
- cout<<"erreur: parentheses \")\" manquante."<<endl;
- break;
- }
- case 6:
- {
- cout<<"erreur interne (bug).\nInterruption du programme"<<endl;
- break;
- }
- }
- }
-
- void calcul::affiche(void) //le nom de la fonction est parlant non?
- {
- for(int j=0;j<taille;j++) cout<<*(opera+j);
- cout<<" = "<<res<<endl;
- }
-
- bool calcul::op(const char &car)//Petite fonction pour verifier le signe.
- {
- if(car=='+' || car=='-')
- return true;
- else
- return false;
- }
-
- int calcul::chsigne(void) // Permet de trouver le signe globales d'une chaines de plusieur signes.(ex: -++-)
- {
- int sig=0;
- for(;op(*(opera+i)) && *(opera+i);i++)
- {
- if(*(opera+i)=='-') sig++;
- }
- i--;
- if(sig%2) return -1;
- else return 1;
- }
-
- double calcul::resultat(void)
- {
- return res;
- }
-
-
- /*************************************************************************************************
- fonction principale :
- **************************************************************************************************/
-
- bool calcul::effectue(const char *ch)
- {
- if (!(*ch)) {error(1); return false;}
- else // recopie la chaine avec celle de la classe
- {
- for(taille=0;*(ch+taille);taille++);
- opera=new char[taille+1];
- for(int j=0;j<=taille;j++)
- {
- *(opera+j)=*(ch+j);
- }
- }
- int save;
- *temp=0;
- for(i=0;*(opera+i) && !err;i++) //boucle principal
- {
- if(isdigit(*(opera+i)) || *(opera+i)=='.')
- {
- if(i==0)
- {
- *temp=cherchenb((opera+i),i);
- i--;
- }
- else {error(2,i+1);return false;}
- }
- else
- {
- switch(*(opera+i))
- {
- case '-':
- case '+':
- {
- res+=*temp;//ajoute temp au resultat.
- *temp=chsigne();//save dans temp le nouveau nombre
- save=i;
- *temp*=cherchenb((opera+i+1),i);
- if(save==i) {error(2,i+1);return false;}//si il n'y a pas de nombre la ou il en faudrait un.(ex: 5+*4)
- break;
- }
- case '*':
- case '/':
- {
- if(i==0) {error(2,1);return false;}
- if(op(*(opera+i+1)))//traitement s'il y a un operateur + ou - devant le nombre a multiplier.
- {
- i++;
- *(temp+1)=chsigne();
- if(*(opera+i-1)=='/') *(temp+1)*=1/(cherchenb((opera+i+1),i));
- else *(temp+1)*=cherchenb((opera+i+1),i);
- }
- else if(isdigit(*(opera+i+1)) || *(opera+i+1)=='.')//s'il y a un directement le nombre
- {
- if(*(opera+i)=='/') *(temp+1)=1/(cherchenb((opera+i+1),i));
- else *(temp+1)=cherchenb((opera+i+1),i);
- }
- else if(!*(opera+i+1)) {error(2,i+1);return false;}//la chaine se finie sur un operateur * ou /.(ex: 5+4*)
- else {error(2,i+2);return false;}//passe la si il y a quelque'chose qui ne devrait pas etre la.(ex: 5*a)
-
-
- //gestion des exposants dans les multiplications et divisions (voir commentaires explicatifs plus bas):
- while(*(opera+i+1)=='p' || *(opera+i+1)=='u')
- {
- i++;
- char genre=*(opera+i);
- int t=1;
- if(op(*(opera+i+1)))
- {
- i++;
- t=chsigne();
- }
- else if(isdigit(*(opera+i+1)));
- else if(!*(opera+i+1)) {error(2,i+1);return false;}
- else {error(2,i+2);return false;}
-
- double u=cherchenb((opera+i+1),i);
- int r=u;
- if(u!=r) {error(3,i);return false;}
- else if(t==-1) r=-r;
- if(genre=='p' || *(temp+1)>0) *(temp+1)=exp(*temp,r);
- else *(temp+1)=-exp(-(*(temp+1)),r);
- }
- *temp*=*(temp+1);
- break;
- }
- //les exposant: p prend le signe :(-2)^2 =-2p2=4 (la premiere operation est la notation "puissance" sur une vrai calculette)
- // u ne le prend pas :-2^2 =-2u2=-4 (, la seconde celle sur mon programme et la troisieme le reultat).
- //(ne marche pas avec les exposants decimaux car je ne sais pas les calculer).
-
- case 'p' :
- case 'u' :
- {
- if(i==0) {error(2,1);return false;}
- while(*(opera+i)=='p' || *(opera+i)=='u')//boucle permettant de mettre a la puissance des exposants (ex:2p2p2).
- {
- char genre=*(opera+i);//savegarde le types d'exposants.
- int t=1;//variable pour le signe de l'exposent(initialiser comme etant '+').
-
- if(op(*(opera+i+1)))//l'exposant a-t-il un signe?
- {
- i++;//se positionne pour la fonction chsigne().
- t=chsigne();//verifie le signe globale.
- }
- else if(isdigit(*(opera+i+1)));//ou es un nombre?
- else if(!*(opera+i+1)) {error(2,i+1);return false;}//erreur si la chane finie sans exposant.
- else {error(2,i+2);return false;}//ou es autre chose ?
-
- double u=cherchenb((opera+i+1),i);//save l'exposant.
- int r=u;//pour verifier si l'exposant est bien un nombre entier
- if(u!=r) {error(3,i);return false;}//si non erreur.
- else if(t==-1) r=-r;//met l'exposant negatif si il l'est(normale).
- if(genre=='p' || *(temp)>0) *temp=exp(*temp,r);//effectue la mise a la puissance.
- else *(temp)=-exp(-(*(temp)),r);
- }
- break;
- }
- default :
- {
- error(2,i+1);
- return false;
- }
- }
- }
- }
- res+=*temp;
- return true;
- }
-
- /*************************************************************************************************
- class fille:
- *************************************************************************************************/
-
- class gestion : protected calcul
- {
- char *ch1,*ch2,*ch3;
- int taille1,taille2,taille3,taille4,*pniveau,pos;
- int parpos;
- void recopie(void);
-
- public:
- gestion(void);
- ~gestion(void);
- bool cal(const char *);
- };
-
- /*************************************************************************************************
- definition des fonctions de la class fille:
- *************************************************************************************************/
-
- gestion::gestion(void)
- {
- ch1=NULL;
- ch2=NULL;
- ch3=NULL;
- pniveau=NULL;
- }
-
- gestion::~gestion(void)
- {
- delete [] ch1;
- delete [] ch2;
- delete [] pniveau;
- }
-
- void gestion::recopie(void) //remplace les parenthese dans ch1 par la valeur calculer et stocher dans ch2.
- {
- delete ch3;
- int tempo=*(pniveau+parpos);
- if(isdigit(*(ch1+tempo-1))) //rajoute un multiplier pour autroriser par exemple 5(2+1).
- taille3=tempo+taille2+(taille1-pos);
- else
- taille3=tempo+taille2+(taille1-pos-1);
- ch3=new char[taille3+1];
- int j;
- for(j=0;j<tempo;j++) *(ch3+j)=*(ch1+j);//copie le debut de ch1 jusqu'a la parenthese calculer.
- if(isdigit(*(ch1+tempo-1))) *(ch3+j++)='*';//rajoute un * si nessecaire.
- for(int k=0;k<taille2;k++,j++) *(ch3+j)=*(ch2+k); //remplace les parentheses par sa valeur totale.
- for(int k=pos+1;k<=taille1;k++,j++) *(ch3+j)=*(ch1+k);//recopie la fin de l'operation.
- delete ch1;taille1=taille3;
- for(ch1=new char[taille1+1],j=0;j<=taille1;j++) *(ch1+j)=*(ch3+j);//remplace ch1 par la chaine ansi cree.
- pos=tempo+taille2-1;//repositionne le "curseur" apres les parenthese.
- }
-
- bool gestion::cal(const char * chtemp) //pour la gestion des parenthese.
- {
- if (!(*chtemp)) {error(1);return false;}
- else //recopie la chaine entree sur celle de la class.
- {
- for(taille1=0;*(chtemp+taille1);taille1++);
- ch1=new char[taille1+1];
- taille4=0;
- for(int j=0;j<=taille1;j++)
- {
- *(ch1+j)=*(chtemp+j);
- if(*(ch1+j)=='(') taille4++;//calcule le nombre de parenthese ouvrante.
- }
- pniveau=new int[taille4];//cree un tableau avec le nombre max de parenthes ouvrante a la suite.
- }
- parpos=0;
- calcul::reinit();//reinitialise la class mere.
- cout<<"\netapes : "<<endl;
- for(pos=0;*(ch1+pos);pos++)
- {
- if(*(ch1+pos)=='(') *(pniveau+parpos++)=pos;//incrit dans le tableau les positions des parenthese ouvrantes.
- if(*(ch1+pos)==')' && parpos-1>=0) //lance le calcule de la valeur entre parenthese
- {
- delete ch2;
- taille2=pos-*(pniveau+(--parpos))+1;ch2=new char[taille2+1];//cree un tableau pour copier ce qui se trouve entre parenthese.
- for(int j=*(pniveau+parpos)+1,k=0;j<pos;j++,k++) *(ch2+k)=*(ch1+j);
- *(ch2+(pos-*(pniveau+parpos))-1)='\0';
-
- if(calcul::effectue(ch2)) //calcule la valeur de ch2 et la transforme en chaine.
- {
- calcul::affiche();
- delete ch2;
- ch2=new char[200];
- if(!transfo(calcul::resultat(),ch2,200)) {error(6);return false;}
- calcul::reinit();
- for(taille2=0;*(ch2+taille2);taille2++);
- recopie();
- }
- else return false;
- }
- else if(*(ch1+pos)==')' && parpos-1<0) {error(4);return false;}
- }
- if(parpos) {error(5);return false;}
- if(calcul::effectue(ch1)) {cout<<"\nresultat:"<<endl;calcul::affiche();}//calcule la valeur finale lorsque qu'il n'y a plus de parenthese.
- else return false;
- cout<<"\n"<<endl;
- return true;//le calcule a marcher.
- }
-
//dans le fichier calculette.cpp
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include "fcalculette.h"
int main(void)
{
gestion a;
char entre[300];
do
{
cout<<"entrez une operation :"<<endl;
cin>>entre;
}while (a.cal(entre));
system("pause");
return 0;
}
//dans le fichier fcalculette.h
#include <ctype.h>
#include <stdio.h>
/*************************************************************************************************
fonction :
**************************************************************************************************/
bool transfo(double don,char *tran,int taille) //transforme un double en chaine de caractere.
{
double nb=don;
int inc=0,i=0,pui=0;
if(nb<0)
{
*tran='-';
nb*=-1;
i++;
}
while(nb>=1) {nb/=10;inc++;}
int rep=0,chi=0;
for(;rep!=5 && i<taille;i++,inc--)
{
nb*=10; // j'ai un probleme avec cette methode un double peut prendre
if(inc==0) *(tran+i++)='.'; // des valeur bizarre du genre 123.0000000000000000354454343...
if(chi==(int)(nb) && inc<0) rep++; // au lieux de 123 j'aimerai savoir ou es le bug car ca peut
else {chi=(int)(nb);rep=0;} // faire bizzare dans le programme et introduire une petite
*(tran+i)=(int)(nb)+48; // erreur.
nb-=(int)(nb);
}
if(rep==5) i-=4;
if(i==taille)
{
*(tran+i-1)='\0';
return false;
}
*(tran+i)='\0';
return true;
}
double exp(double nb,int ex) //pour les calcules avec exposants
{
double res=nb;
if(!ex)
{
if(nb>=0) res=1;
else res=-1;
ex=1;
}
while(ex!=1 && ex!=-1)
{
if(ex>0) ex--;
else ex++;
res*=nb;
}
if(ex==-1) res=1/res;
return res;
}
double cherchenb(const char *ope,int &cur) //transforme une chaine de caractere en nombre
{
double nobe=0,nobd=0;
int dec=-1,pos=0;
for(;isdigit(*(ope+pos)) || (*(ope+pos)=='.' && dec==-1);pos++)
{
if(*(ope+pos)=='.') dec=0;
else if(dec==-1)
{
nobe*=10;
nobe+=*(ope+pos)-48;
}
else
{
nobd*=10;
nobd+=*(ope+pos)-48;
dec++;
}
}
cur+=pos;
if(nobd==0) return nobe;
else return nobe+(nobd/(exp(10,dec)));
}
/*************************************************************************************************
class mere:
**************************************************************************************************/
class calcul
{
double res,*temp;
int taille,i;
char *opera;
bool op(const char &);
int chsigne(void);
protected: //protected pour que la classe fille puisse l'utiliser.
int err;
void error(int,int);
double resultat(void);
public:
calcul(void);
~calcul(void);
void affiche(void);
void reinit(void);
bool effectue(const char *);
};
/*************************************************************************************************
definition des fonctions de la class mere:
**************************************************************************************************/
calcul::calcul(void)
{
res=0;temp=0;
err=0;
taille=0;i=0;
temp=new double[2];
opera=NULL;
}
calcul::~calcul(void)
{
delete [] opera;
delete [] temp;
}
void calcul::reinit(void)
{
delete [] opera;
res=0;err=0;i=0;
taille=0;
}
void calcul::error(int ce,int pos=0) //gestions des erreurs dans l'operation rentré avec affichage de l'emplacement de celle ci.
{
err=1;
switch (ce)
{
case 1:
{
cout<<"erreur chaine de calcul vide."<<endl;
break;
}
case 2:
{
cout<<"erreur de syntaxe position:"<<pos<<endl;
for(int j=0;j<taille;j++) cout<<*(opera+j);
cout<<endl;
for(int j=0;j<(pos-1);j++) cout<<" ";
cout<<"|"<<endl;
break;
}
case 3:
{
cout<<"ce programme ne gere pas les exposants decimals."<<endl;
for(int j=0;j<taille;j++) cout<<*(opera+j);
cout<<endl;
for(int j=0;j<(pos-1);j++) cout<<" ";
cout<<"|"<<endl;
break;
}
case 4:
{
cout<<"erreur: parentheses \"(\" manquante."<<endl;
break;
}
case 5:
{
cout<<"erreur: parentheses \")\" manquante."<<endl;
break;
}
case 6:
{
cout<<"erreur interne (bug).\nInterruption du programme"<<endl;
break;
}
}
}
void calcul::affiche(void) //le nom de la fonction est parlant non?
{
for(int j=0;j<taille;j++) cout<<*(opera+j);
cout<<" = "<<res<<endl;
}
bool calcul::op(const char &car)//Petite fonction pour verifier le signe.
{
if(car=='+' || car=='-')
return true;
else
return false;
}
int calcul::chsigne(void) // Permet de trouver le signe globales d'une chaines de plusieur signes.(ex: -++-)
{
int sig=0;
for(;op(*(opera+i)) && *(opera+i);i++)
{
if(*(opera+i)=='-') sig++;
}
i--;
if(sig%2) return -1;
else return 1;
}
double calcul::resultat(void)
{
return res;
}
/*************************************************************************************************
fonction principale :
**************************************************************************************************/
bool calcul::effectue(const char *ch)
{
if (!(*ch)) {error(1); return false;}
else // recopie la chaine avec celle de la classe
{
for(taille=0;*(ch+taille);taille++);
opera=new char[taille+1];
for(int j=0;j<=taille;j++)
{
*(opera+j)=*(ch+j);
}
}
int save;
*temp=0;
for(i=0;*(opera+i) && !err;i++) //boucle principal
{
if(isdigit(*(opera+i)) || *(opera+i)=='.')
{
if(i==0)
{
*temp=cherchenb((opera+i),i);
i--;
}
else {error(2,i+1);return false;}
}
else
{
switch(*(opera+i))
{
case '-':
case '+':
{
res+=*temp;//ajoute temp au resultat.
*temp=chsigne();//save dans temp le nouveau nombre
save=i;
*temp*=cherchenb((opera+i+1),i);
if(save==i) {error(2,i+1);return false;}//si il n'y a pas de nombre la ou il en faudrait un.(ex: 5+*4)
break;
}
case '*':
case '/':
{
if(i==0) {error(2,1);return false;}
if(op(*(opera+i+1)))//traitement s'il y a un operateur + ou - devant le nombre a multiplier.
{
i++;
*(temp+1)=chsigne();
if(*(opera+i-1)=='/') *(temp+1)*=1/(cherchenb((opera+i+1),i));
else *(temp+1)*=cherchenb((opera+i+1),i);
}
else if(isdigit(*(opera+i+1)) || *(opera+i+1)=='.')//s'il y a un directement le nombre
{
if(*(opera+i)=='/') *(temp+1)=1/(cherchenb((opera+i+1),i));
else *(temp+1)=cherchenb((opera+i+1),i);
}
else if(!*(opera+i+1)) {error(2,i+1);return false;}//la chaine se finie sur un operateur * ou /.(ex: 5+4*)
else {error(2,i+2);return false;}//passe la si il y a quelque'chose qui ne devrait pas etre la.(ex: 5*a)
//gestion des exposants dans les multiplications et divisions (voir commentaires explicatifs plus bas):
while(*(opera+i+1)=='p' || *(opera+i+1)=='u')
{
i++;
char genre=*(opera+i);
int t=1;
if(op(*(opera+i+1)))
{
i++;
t=chsigne();
}
else if(isdigit(*(opera+i+1)));
else if(!*(opera+i+1)) {error(2,i+1);return false;}
else {error(2,i+2);return false;}
double u=cherchenb((opera+i+1),i);
int r=u;
if(u!=r) {error(3,i);return false;}
else if(t==-1) r=-r;
if(genre=='p' || *(temp+1)>0) *(temp+1)=exp(*temp,r);
else *(temp+1)=-exp(-(*(temp+1)),r);
}
*temp*=*(temp+1);
break;
}
//les exposant: p prend le signe :(-2)^2 =-2p2=4 (la premiere operation est la notation "puissance" sur une vrai calculette)
// u ne le prend pas :-2^2 =-2u2=-4 (, la seconde celle sur mon programme et la troisieme le reultat).
//(ne marche pas avec les exposants decimaux car je ne sais pas les calculer).
case 'p' :
case 'u' :
{
if(i==0) {error(2,1);return false;}
while(*(opera+i)=='p' || *(opera+i)=='u')//boucle permettant de mettre a la puissance des exposants (ex:2p2p2).
{
char genre=*(opera+i);//savegarde le types d'exposants.
int t=1;//variable pour le signe de l'exposent(initialiser comme etant '+').
if(op(*(opera+i+1)))//l'exposant a-t-il un signe?
{
i++;//se positionne pour la fonction chsigne().
t=chsigne();//verifie le signe globale.
}
else if(isdigit(*(opera+i+1)));//ou es un nombre?
else if(!*(opera+i+1)) {error(2,i+1);return false;}//erreur si la chane finie sans exposant.
else {error(2,i+2);return false;}//ou es autre chose ?
double u=cherchenb((opera+i+1),i);//save l'exposant.
int r=u;//pour verifier si l'exposant est bien un nombre entier
if(u!=r) {error(3,i);return false;}//si non erreur.
else if(t==-1) r=-r;//met l'exposant negatif si il l'est(normale).
if(genre=='p' || *(temp)>0) *temp=exp(*temp,r);//effectue la mise a la puissance.
else *(temp)=-exp(-(*(temp)),r);
}
break;
}
default :
{
error(2,i+1);
return false;
}
}
}
}
res+=*temp;
return true;
}
/*************************************************************************************************
class fille:
*************************************************************************************************/
class gestion : protected calcul
{
char *ch1,*ch2,*ch3;
int taille1,taille2,taille3,taille4,*pniveau,pos;
int parpos;
void recopie(void);
public:
gestion(void);
~gestion(void);
bool cal(const char *);
};
/*************************************************************************************************
definition des fonctions de la class fille:
*************************************************************************************************/
gestion::gestion(void)
{
ch1=NULL;
ch2=NULL;
ch3=NULL;
pniveau=NULL;
}
gestion::~gestion(void)
{
delete [] ch1;
delete [] ch2;
delete [] pniveau;
}
void gestion::recopie(void) //remplace les parenthese dans ch1 par la valeur calculer et stocher dans ch2.
{
delete ch3;
int tempo=*(pniveau+parpos);
if(isdigit(*(ch1+tempo-1))) //rajoute un multiplier pour autroriser par exemple 5(2+1).
taille3=tempo+taille2+(taille1-pos);
else
taille3=tempo+taille2+(taille1-pos-1);
ch3=new char[taille3+1];
int j;
for(j=0;j<tempo;j++) *(ch3+j)=*(ch1+j);//copie le debut de ch1 jusqu'a la parenthese calculer.
if(isdigit(*(ch1+tempo-1))) *(ch3+j++)='*';//rajoute un * si nessecaire.
for(int k=0;k<taille2;k++,j++) *(ch3+j)=*(ch2+k); //remplace les parentheses par sa valeur totale.
for(int k=pos+1;k<=taille1;k++,j++) *(ch3+j)=*(ch1+k);//recopie la fin de l'operation.
delete ch1;taille1=taille3;
for(ch1=new char[taille1+1],j=0;j<=taille1;j++) *(ch1+j)=*(ch3+j);//remplace ch1 par la chaine ansi cree.
pos=tempo+taille2-1;//repositionne le "curseur" apres les parenthese.
}
bool gestion::cal(const char * chtemp) //pour la gestion des parenthese.
{
if (!(*chtemp)) {error(1);return false;}
else //recopie la chaine entree sur celle de la class.
{
for(taille1=0;*(chtemp+taille1);taille1++);
ch1=new char[taille1+1];
taille4=0;
for(int j=0;j<=taille1;j++)
{
*(ch1+j)=*(chtemp+j);
if(*(ch1+j)=='(') taille4++;//calcule le nombre de parenthese ouvrante.
}
pniveau=new int[taille4];//cree un tableau avec le nombre max de parenthes ouvrante a la suite.
}
parpos=0;
calcul::reinit();//reinitialise la class mere.
cout<<"\netapes : "<<endl;
for(pos=0;*(ch1+pos);pos++)
{
if(*(ch1+pos)=='(') *(pniveau+parpos++)=pos;//incrit dans le tableau les positions des parenthese ouvrantes.
if(*(ch1+pos)==')' && parpos-1>=0) //lance le calcule de la valeur entre parenthese
{
delete ch2;
taille2=pos-*(pniveau+(--parpos))+1;ch2=new char[taille2+1];//cree un tableau pour copier ce qui se trouve entre parenthese.
for(int j=*(pniveau+parpos)+1,k=0;j<pos;j++,k++) *(ch2+k)=*(ch1+j);
*(ch2+(pos-*(pniveau+parpos))-1)='\0';
if(calcul::effectue(ch2)) //calcule la valeur de ch2 et la transforme en chaine.
{
calcul::affiche();
delete ch2;
ch2=new char[200];
if(!transfo(calcul::resultat(),ch2,200)) {error(6);return false;}
calcul::reinit();
for(taille2=0;*(ch2+taille2);taille2++);
recopie();
}
else return false;
}
else if(*(ch1+pos)==')' && parpos-1<0) {error(4);return false;}
}
if(parpos) {error(5);return false;}
if(calcul::effectue(ch1)) {cout<<"\nresultat:"<<endl;calcul::affiche();}//calcule la valeur finale lorsque qu'il n'y a plus de parenthese.
else return false;
cout<<"\n"<<endl;
return true;//le calcule a marcher.
}
Fichier Zip
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
|