5 8 * 4 9 - /=-8
Apparentemente sembra facile : ad ogni numero nella stringa fai un push nello stack, ad ogni operatore calcoli e fai un pop.
i problemi sono sulla lettura della stringa:
1) devo riconoscere i numeri delimitati dagli spazi
2) gli spazi possono essere uno o tanti, il programma deve essere "immune"
3) non sono ammesse scritture come:5a 8 * 4 9 - /
4) operatori doppi come ++ se non staccati da spazio non sono ammessi, nemmeno:5+ 8 * 4 9 -
5) bisogna riconoscere se il numero degli operatori è corretto 5 3 + + (sbagliato e devo stampare buffer underflow).
Mi domando se per gestire tutte queste cose non sia necessario studiarsi le espressioni regolari. Che tra l'altro non so nemmeno cosa
siano, suppongo facciano ricerche molto più evolute.
Io ho scritto un programma , è un prototipo, ripeto, pensavo fosse molto più semplice...invece no.
Mi piacerebbe sapere se ci sono modi per non incappare in molteplici if per le varie ricerche nella stringa.
Per ora uso solo numeri interi, quando invece dovrei usare i float.
Ma cosi facendo ho un controllo in più
5.3 4.9 + va bene
ma deve essere in grado di capire che il punto spaiato è un errore:
5.3 4.9 . + errore (un'idea ce l'avrei).
Il programma è questo. Alcune cose non mi piacciono e vanno cambiate:
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define UNDER_STACK 1
#define SIZE_STACK 200
int check (char *token,int *push,int stak[], int *number);
int push_stack (int *number,int *push,int stack[]);
int operand (char *token,int *push,int stack[],int *number);
void somma (int *push,int stack[]);
void sottrazione (int *push,int stack[]);
void moltiplicazione (int *push,int stack[]);
void divisione (int *push,int stack[]);
//---------------------------------------------------------------------
// test per vedere se il token è formato
// da soli numeri
//---------------------------------------------------------------------
int check( char *token,int *push,int stack[],int *number)
{
char *p=token;
while (*p!='\0')
{
if (isdigit(*p)==0 )
return -1;
p++;
}
*number=atoi(token); // traformo la stringa in intero
return 1;
}
//---------------------------------------------------------------------
// inserisco il numero nello stack
//---------------------------------------------------------------------
int push_stack(int *number,int *push,int stack[])
{
if (*push<SIZE_STACK) //superfluo se non usi input
{ //interattivi come fgets
++(*push);
stack[(*push)]=(*number);
return 1;
}
return -1;
}
//---------------------------------------------------------------------
// controllo a quale operazione corrisponde
// il token e intraprendo operazione
// corrispondente
//---------------------------------------------------------------------
int operand ( char *token,int *push,int stack[],int *number)
{
static char add[]="+";
static char sot[]="-";
static char mol[]="*";
static char div[]="/";
char *p=token;
if ((strcmp (p,add)==0))
{
somma(push,stack);
return 1;
}
if ((strcmp (p,sot)==0))
{
sottrazione(push,stack);
return 1;
}
if ((strcmp (p,mol)==0))
{
moltiplicazione(push,stack);
return 1;
}
if ((strcmp (p,div)==0))
{
divisione(push,stack);
return 1;
}
return 0;
}
//---------------------------------------------------------------------
// funzione somma
//---------------------------------------------------------------------
void somma(int *push,int stack[])
{
if (*push>=UNDER_STACK)
{
stack[(*push-1)]=stack[(*push-1)]+stack[(*push)];
--(*push);
}
else
{
puts("buffer underflow");
exit(0);
}
}
//---------------------------------------------------------------------
// funzione sottrazione
//---------------------------------------------------------------------
void sottrazione (int *push,int stack[])
{
if (*push>=UNDER_STACK)
{
stack[(*push-1)]=stack[(*push-1)]-stack[(*push)];
--(*push);
}
else
{
puts("buffer underflow");
exit(0);
}
}
//---------------------------------------------------------------------
// funzione moltiplicazione
//---------------------------------------------------------------------
void moltiplicazione (int *push,int stack[])
{
if (*push>=UNDER_STACK)
{
stack[(*push-1)]=stack[(*push-1)]*stack[(*push)];
--(*push);
}
else
{
puts("buffer underflow");
exit(0);
}
}
//---------------------------------------------------------------------
// funzione divisione
//---------------------------------------------------------------------
void divisione (int *push,int stack[])
{
if (*push>=UNDER_STACK)
{
stack[(*push-1)]=stack[(*push-1)]/stack[(*push)];
--(*push);
}
else
{
puts("buffer underflow");
exit(0);
}
}
//---------------------------------------------------------------------
int main(void)
{
char str[512]="5 8 * 4 9 - /";
const char s[2] = " ";
int stack[SIZE_STACK];
char *token;
int push=-1;
int number=0;
token = strtok(str, s);
while( token != NULL )
{
if ( (check(token,&push,stack,&number))==1)// se test numero ok
{
if ((push_stack(&number,&push,stack))!=1)// inserisci nello stack
{
puts("buffer overflow");
exit (0);
}
}
else // altrimenti potrebbe essere un operatore
{
if (operand(token,&push, stack,&number)!=1)
{
puts ("scrittura errata\n");
return 0;
}
}
token = strtok(NULL, s);
}
if (push==0)
printf("\nrisultato %d\n",stack[0]);
else
puts ("espressione malformata");
return 0;
}
input:
Codice: Seleziona tutto
5 8 * 4 9 - /Codice: Seleziona tutto
risultato -8
Codice: Seleziona tutto
5a 10 +Codice: Seleziona tutto
scrittura errata
Codice: Seleziona tutto
5 10 + + +Codice: Seleziona tutto
buffer underflowNon so se ho considerato tutto e non garantisco sia esente da bugs.
Più che altro mi domando come fare confronti nella stringa in modo elegante...cosa scrivereste voi.
Sarebbe tutto più semplice con scanf e man mano controllare e mettere nello stack, ma io voglio farlo su una stringa
Grazie a tutti e nel caso non ci si senta buon anno


