[Duda] token/strtok /Notacion Polaca Inversa

Iniciado por digitalx2, 22 Septiembre 2013, 22:31 PM

0 Miembros y 1 Visitante están viendo este tema.

digitalx2

necesito seprarar una cadena de caracteres, que enrealidad seran numeros y operadores matematicos
pero no logro asignar lso valores de *prt a una cadena para despues haceres push (meterlos a mi estructura/pila  A") el strtok no lo se usar muy bien , soy nuevo en cadenas y se me complica mucho ._ . todo lo que esta comentado es por que no funciona.. osea deja de funcionar el programa...


por ejemplo (para los que no conozcan la notacion polaca inversa)

mi input es:

5 6 9 + 8 5 *
esto quedaria como
5 11 40
siempre el operador matematico se aplicara a los dos ultimos valores
entonces necesito separar la cadena inicial para saber si es digito o un operador matematico
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#define MAX 100 /* max size of operand or operator */
typedef int stackEntry;
typedef struct {stackEntry data[MAX]; int index; }Stack;

int isFull(Stack);
int isEmpty(Stack);
void push(Stack*,stackEntry);
stackEntry pop(Stack*);


void create(Stack *s){s->index=-1;}

int main(void)
{
Stack A;
int type,i;
stackEntry k;
stackEntry op2;
char s[MAX],aux[MAX];
create(&A);
/* if(A.index==-1){printf(" Pila Inicializada index: %d" ,A.index);} solo una prueba*/
push(&A,6);push(&A,5);push(&A,7);pop(&A);pop(&A);pop(&A);
printf("\nPush y Pop funcionan correctamente");
getche();
system("cls");
printf("Escribe\n"); i=0;
{
char s2[4] = " \n\t";
char *ptr;
fgets(s,MAX,stdin);
/*system("cls");
/* printf( "A stack = %s\n", s );*/

ptr = strtok( s, s2);    /* Primera llamada => Primer token*/
printf( "%s\n", ptr );
while( (ptr = strtok( NULL, s2 )) != NULL )    /*Posteriores llamadas*/

/*strcpy(aux,ptr); i++; printf("\n aux var = %s",aux);

/*if(isdigit(*ptr)){ k=atoi(ptr);push(&A,k);}
/*if(ptr=='+'){push(&A,pop(&A)+pop(&A));}
if(ptr=='*'){push(&A,pop(&A)*pop(&A));}
*/
printf( "%s\n", ptr);
/*printf("\npop:%d",A.data[A.index]);*/
return 0;
}

}

int isFull(Stack s){
if (s.index==MAX-1)
return 1;
else
return 0;}

int isEmpty(Stack s){
if(s.index==-1)
return 1;
else  return 0;
}

void push(Stack *s, stackEntry dato)
{
if(isFull(*s)){printf("\nError pila llena"); return;}
s->index+=1;
s->data[s->index] = dato;
printf("\ndato:%d ",dato)/*use este printf para comprobar que mi push y pop funcionaran adecuadamente*/;
}


stackEntry pop(Stack*s)
{
if(isEmpty(*s)){printf("error: stack empty\n"); return -1;}
printf("\npop: %d\n",s->data[s->index--]);
return 1;

}





eferion

Cita de: digitalx2 en 22 Septiembre 2013, 22:31 PM
mi input es:

5 6 9 + 8 5 *
esto quedaria como
5 11 40

O se me ha olvidado sumar o esto debería quedar tal que:
5 15 40

Es importante porque si no puedes ponerte a buscar errores donde no los hay.

Más cosillas. Como norma general los índices se tiende a incrementarlos despues de añadir el elemento al vector... no antes. Básicamente porque si se produce un problema mientras añades el elemento al vector al final tienes que acordarte de volver a reducir el valor del puntero... y es preferible perder un dato a recuperar un valor no inicializado. Esto te lo digo por el uso que haces de index.


ptr = strtok( s, s2);    /* Primera llamada => Primer token*/
printf( "%s\n", ptr );
while( (ptr = strtok( NULL, s2 )) != NULL )    /*Posteriores llamadas*/


El problema que te va a generar esta estructura es que el primer token lo vas a perder... prueba a meter esta secuencia 5 5 +... no funciona.

Si quieres convservar el primer token, que imagino que sí, usa un bucle dowhile...


ptr = strtok( s, s2);    /* Primera llamada => Primer token*/
printf( "%s\n", ptr );
                do
                {
                  // Aqui aun conservas el primer token, en las siguientes pasadas
                  // tendras los siguientes tokens

                 // ...
                }
while( (ptr = strtok( NULL, s2 )) != NULL )    /*Posteriores llamadas*/


Otra cosa más. La función 'isdigit' solamente comprueba un caracter... luego si tienes pensado permitir la entrada de números de dos o más dígitos tendrás que comprobar todo el token para evitar errores.

Y para terminar un último fallo:


stackEntry pop(Stack*s)
{
if(isEmpty(*s)){printf("error: stack empty\n"); return -1;}
printf("\npop: %d\n",s->data[s->index--]);
return 1;

}


Mola esta función... imagínate una pila con elementos aleatorios... haz un pop y te adivino lo que te va a devolver esta función: siempre 1... bueno, al menos mientras queden elementos en el stack.

ese return 1 no debería estar así... la función más bien debería tener una forma tal que:


stackEntry pop(Stack*s)
{
if(isEmpty(*s)){printf("error: stack empty\n"); return -1;}
        stackEntry dato = s->data[s->index--];
printf("\npop: %d\n",dato);
return dato;
}


Y para rematar unos consejos:

* no pongas varias instrucciones en la misma línea... queda feo, generas código menos legible y que además es más complicado de depurar y no vas a ganar espacio. Una línea, una instrucción... hazme caso que lo vas a agradecer.

* Elimina variables sin uso: no aportan nada al código y dificultan su lectura: i, op2, type.

Un saludo.