[C con Clase] interprete de expresiones matematicas
Programante
programante en gmail.com
Mar Jul 15 11:20:14 CEST 2008
rodolfo rosso paz escribió:
> Hola a todos nuevamente, de nuevo por aqui molestando:
>
> queria saber si hay una forma de evaluar una expresion matamatica
> contenida en una cadena y obtener el resultado :
>
>
> Ejemplo.
>
> int x = 3
> var = "x + 5"
> int resultado = evaluar(var)
>
> y que resultado contenga 8. me dicen que en java hay una funcion
> EVAL() y yo recuerdo que en clipper tambien habia lo que se le llamaba
> macros y solo era necesario colocar & delante de var, y con eso
> obtenia el resultado de la formula contenida en la cadena.
>
> ¿hay forma de hacerlo en c++?
>
>
> Gracias de antemano
>
> Rodolfo
En C++ no hay una función eval(), como es el caso de javascript (en java
tampoco se puede), ya que C es un lenguaje compilado, tu programa tiene
instrucciones en código máquina, no el compilador, que es quien sabe
hacer la suma. Por lo tanto, para que eso te funcione tienes que crear a
mano la lógica de evaluar.
Si sabes que sólo va a haber sumas, te basta separar por el símbolo + y
sumar los símbolos. Tampoco es lo mismo si te vale ejecutar las
operaciones en orden que si te interesa que * y / tengan prioridad, que
haya paréntesis... En esos casos te convendría generar una pila y
recorrer en preorden las operaciones inorden que le pasas.
#include <stdio.h>
int x;
enum Operaciones { Suma='+', Resta='-' };
int HazOperacion(int Valor1, int Valor2, enum Operaciones Op) {
switch (Op) {
case Suma:
return Valor1 + Valor2;
case Resta:
return Valor1 - Valor2;
}
}
int Evaluar(const char* Cadena) {
enum Operaciones Operacion = Suma; //Qué operación estamos haciendo
int Resultado = 0; //El resultado parcial
int Valor = 0; //Operando
int i; //Para iterar por cadena
for (i=0; Cadena[i]; i++) {
switch (Cadena[i]) {
case ' ': break;
case '0'...'9':
Valor = Valor*10 + (Cadena[i] - '0');
break;
case 'x':
Valor = Valor*10 + x;
break;
case '+':
case '-':
Resultado = HazOperacion(Resultado, Valor, Operacion);
Valor = 0;
Operacion = Cadena[i];
break;
default:
fprintf(stderr, "Caracter desconocido %c\n", Cadena[i]);
}
}
return HazOperacion(Resultado, Valor, Operacion); //Si nos queda
pendiente alguna operación hacerla
}
int main() {
const char* var = "x + 5";
x = 3;
printf("%s = %d\n", var, Evaluar(var));
return 0;
}
Este código suma y resta números, así como la variable x. Para la
mayoría de las operaciones normales, funciona, pero en otras puede no
dar lo esperado. Por ejempo tratará "2x + 5" como 28 en vez de 11.
También juago con el elemento nulo de la suma y la resta, por lo que
pasar a multiplicar se complica, pero es un buen código de partida para
estudiar la máquina de estados y cómo ir parseandolas operaciones.
Más información sobre la lista de distribución Cconclase