Newsgroup: it.comp.lang.c++
Titolo: ESPRESSIONI matematichehelp

int totale = int(espressione) - int('0');
Ho provato ma non risolve il mio problema: si, l'output è il numero e non il carattere ascii ma mi legge solo il primo numero. esempio
il mio input è : 5 + 5 
l'output è : 5
anche facendo (sempre input): 5+5
l'output è: 5
legge il primo numero.
----------------------------------------------
Virgilio Mail - Il tuo indirizzo E-mail gratis
http://mail.virgilio.it
--
Posted from [212.48.4.47] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Ciao!
Riassunto delle puntate precedenti: 
team...@virgilio.it
 sta cercando di
valutare espressioni inserite dall'utente in C++.
Purtroppo ti sei accorto che non è così semplice. Quello che leggi da
tastiera è niente + che una stringa, alla meglio un numero (il primo
inserito).
Ci sono una serie di algoritmi che trasformano la stringa in qualcosa di
comprensibile e calcolabile dal computer, il più semplice (e l'unico che
conosco :-) viene definito 'a discesa ricorsiva' e ne trovi una spiegazione
dettagliata a questo indirizzo:
http://www.programmazione.it/linguaggi/c/parser.htm
A quest'altro indirizzo ne trovi una implementazione già pronta in C++,
fatta dallo stesso autore dell'articolo:
http://members.xoom.com/prgit/cpp/gparser.zip
 . Te l'ho scritto qua perché
il collegamento che si trova in fondo all'articolo non va...
Ciao!
Kojak
vrke...@hotmail.com
http://space.tin.it/io/viscorci
Life would be much easier if I had the source code.

Infatti non è così semplice, il problema è che tu leggi solo un
carattere,mentre tutti gli altri rimango nello stdin in attesa di essere
letti
Cmq eccoti un listato funzionante di una calcolatrice che ho fatto oggi (non
è ottimizzato al massimo). L'unica cosa non implementata sono le parentesi,
ma ci si può lavorare sopra.
Se non ti è chiaro qualcosa fammi sapere.
#include <iostream.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define MAX_NUMERI 5
double ctoi(int c);
bool issegno(int c);
void EseguiOperazione(char operazione_da_eseguire);
void EseguiOperazione(char operazione_da_eseguire, char
operazione_da_eseguire2);
void InizializzaVettori();
void FaiOperazione(char op, int i);
double numero[ MAX_NUMERI ]; // vettore che contiene i numeri letti
char operazione[ MAX_NUMERI ]; // vettore che contiene le operazioni
void main(void)
{
 int ch; // codice ascii di ogni carattere letto
 int lastch;
 bool meno=false;
 int i=0; // contatore per i vettori
 int io=0;
 int ncifre_decimali = 0; // utilizzato per costruire i double
 InizializzaVettori();
 // ripeto la lettura finchè non viene premuto enter
 while(ch != '\n')
 {
  ch = getchar(); // leggo il codice ascii del carattere premuto
  // proseguo solo se non è enter
  if(ch != '\n')
  {
   if(issegno(ch)) // se il carattere è un segno
   {
    ncifre_decimali=0; // azzero le cifre decimali perchè ho terminato la
lettura di un numero
    if(ch != '-')
    {
     operazione[i] = (char) (ch); // mi salvo l'operazione nell'apposito
vettore (trasformandola prima in carattere)
     i++; // aumento l'indice dei vettori
     lastch=(char)ch;
    }
    else
    {
     meno = true;
     if(!issegno(lastch))
     {
      operazione[i] = '+';
      i++;
      i=i;
     }
    }
   }
   else
    if(isdigit(ch) && ncifre_decimali == 0) // se il carattere è un numero e
sto leggendo le cifre prima della virgola allora...
    {
     numero[i] = numero[i]*10 + ctoi(ch); // ... moltiplico per 10 il
vecchio numero e ci aggiungo quello nuovo
     if(meno)
     {
      numero[i] = numero[i] * -1;
      meno = false;
     }
     lastch=(char)ch;
    }
    else
    if(isdigit(ch) && ncifre_decimali > 0) // altrimenti se sto leggendo una
cifra decimale
    {
     numero[i] = numero[i] + (ctoi(ch) / (pow(10,ncifre_decimali))); //
sommo al vecchi numero quello letto diviso per il la potenza di 10 pari
                   // alla cifra decimale che dovrà occupare (eg se leggo un
centesimo sara 1 / 10^2 = 1 / 100
     ncifre_decimali++; // aumento il contatore per la prossima lettura
     lastch=(char)ch;
    }
   if(ch == '.') // se il carattere è il punto
    ncifre_decimali++; // metto il numero di cifre decimali a 1
  }
 }
 // eseguo tutte le operazioni con le rispettive priorità
 EseguiOperazione('*', '/');
// EseguiOperazione('/');
 EseguiOperazione('-');
 EseguiOperazione('+');
 cout << endl;
 cout << numero[0];
}
// conversione di un carattere in un double
double ctoi(int c)
{
 return c - (int)('0');
}
// verifico se un carattere è uno dei segni
bool issegno(int c)
{
 if(c == '+' || c == '-' || c == '*' || c == '/')
  return true;
 else
  return false;
}
/*
ESEMPIO
  5 * 3 + 99
  numero[0] = 5  operazione[0] = '*'
  numero[1] = 3  operazione[1] = '+'
  numero[2] = 99 operazione[2] = ' '
*/
void EseguiOperazione(char operazione_da_eseguire, char
operazione_da_eseguire2)
{
 // ripeto l'operazione per tutti i numeri
 for(int i=0; i<MAX_NUMERI; i++)
  // se l'operazione combacia
  if(operazione[i] == operazione_da_eseguire)
  {
   FaiOperazione(operazione_da_eseguire, i);
   i--;
  }
  else
  if(operazione[i] == operazione_da_eseguire2)
  {
   FaiOperazione(operazione_da_eseguire2, i);
   i--;
  }
}
void EseguiOperazione(char operazione_da_eseguire)
{
 // ripeto l'operazione per tutti i numeri
 for(int i=0; i<MAX_NUMERI; i++)
  // se l'operazione combacia
  if(operazione[i] == operazione_da_eseguire)
  {
   FaiOperazione(operazione_da_eseguire, i);
   i--;
  }
}
void InizializzaVettori()
{
 for(int i=0; i<MAX_NUMERI; i++)
 {
  numero[i] = 0;
  operazione[i] = ' ';
 }
}
void FaiOperazione(char op, int i)
{
 switch(op)
 {
  // eseguo l'operazione opportuna
  case '+':
   {
    numero[i] = numero[i] + numero[i+1];
    break;
   }
  case '-':
   {
    numero[i] = numero[i] - numero[i+1];
    break;
   }
  case '*':
   {
    numero[i] = numero[i] * numero[i+1];
    break;
   }
  case '/':
   {
    numero[i] = numero[i] / numero[i+1];
    break;
   }
 }
 operazione[i] = operazione[i+1];
 // a qusto punto devo far scalare tutte le altre operazioni e i numeri di 1
posto
 for(int k=i+1; k< (MAX_NUMERI - 1); k++)
 {
  numero[k] = numero[k+1];
  operazione[k] = operazione[k+1];
 }
 numero[MAX_NUMERI-1]=0;
}

Credo che tu debba usare delle funzioni per calcolare le espressioni.
int espressione(char  *str, int &i)
{
     ......
}
dove char *str   è la stringa ad es.   "1+2+3"
e i può essere usato come indice per leggere la stringa
magari in modo ricorsivo.

legge il primo numero.
In C++ non esiste nessua funzione gia' pronta che valuti una stringa
contenente una espressione e ne calcoli il risultato.
E' pero' un esercizio di programmazione che viene spesso proposto
e che e' stato usato anche nel classico "The C++ Programming
Language" (terza edizione) come esempio di programma completo.
La spiegazione presente sul testo e' completa ma onestamente
non so se la lettura di tale parte pero' realmente possa
giovare a chi non ha gia' una infarinatura sull'argomento
(BNF, tokenizer, analizzatori ricorsivi a discesa).
Il primo calcolo espressione che ho scritto in vita mia era in
BASIC, non ricorsiva e basata sulle stringhe.
Cercava la prima parentesi destra e tornava indietro sino alla
prima parentesi sinistra. Isolata questa parte eseguiva le
operazioni indicate leggendo un carattere alla volta e
ragionando di conseguenza (non gestiva la priorita' di "*" e
"/" rispetto a "+" e "-" e quindi "1+3*4" dava risultato 16).
Una volta trovato il risultato dell'espressione fra parentesi
lo sostituiva nella stringa originale e ricominciava da capo.
Potrebbe essere un inizio
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 dettagliata a questo indirizzo:
Se vi va una implementazione in flex+bison (insomma, per Linux,
semplificando un po'): 
http://wwwcdf.pd.infn.it/MLO/dtc.tar.gz
 ...
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

semplificando un po'): 
http://wwwcdf.pd.infn.it/MLO/dtc.tar.gz
 ...
Dico sempre le stesse cose... ma usare flex+bison per uno che
non ha idea di cosa sia un tokenizer, una grammatica espressa
in BNF o un parser ricorsivo a discesa penso non serva a
un granche'.
E chi propone di fare valore=int(espressione) certamente non
ha la minima idea di cosa siano queste cose.
E comunque si tratta di roba portabile, non linux.
