CrappyCoder - 1 year ago 83
C Question

Trouble using push in stack

I'm learning data structures and I have a problem pushing data into my stack. Even though I have used the same push function early in the program it doesn't seem to push characters. The program should transform infix expressions to postfix

When given the number "1+2" it should return "12+", however it only returns "12"

``````       bool revisar(char * inf, stack p){
inicializa(&p);
Nodo D;
char pos[MAX];
int i=0;
int j=0;
while(inf[i]!='\0')
{//WHILE
if(inf[i]>='0' && inf[i]<='9')
{
pos[j++]=inf[i++];
}
if(inf[i]=='(')
{
D.caracter=inf[i++];
push(&p,D);
}
if(inf[i]==')')
{

while(top(p).caracter!='(')
{
pos[j++]=pop(&p).caracter;
}
if(top(p).caracter=='(')
pop(&p);
i++;
}
else
{
if(inf[i]=='+'||inf[i]=='-'||inf[i]=='*'||inf[i]=='/')
{
if(empty(p)||top(p).caracter=='(')
{
D.cara

cter=inf[i++];
push(&p,D);
if(empty(p));
printf("NNNNNNOOOOOOOOOOOOOOOOOOOOOO"); **Here it prints that the stack is still empty....
}
else
{
if(menorpre(top(p).caracter,inf[i]))
{
D.caracter=inf[i++];
push(&p,D);
}
else
{
pos[j++]=pop(&p).caracter;
if(!empty(p))
{
if(top(p).caracter!='(')

pos[j++]=pop(&p).caracter;
}
else
{
D.caracter=inf[i++];
push(&p,D);
}
}
}
}
}
}
while(!empty(p)){
printf("ddd");
pos[j++]=pop(&p).caracter;
}
pos[j]='\0';

printf("\n \n");
printf("i=%d,j=%d",i,j);
printf("LA CADENA EN POSFIJO ES: ");
puts(pos);
}
``````

My stack library

``````#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include "pila.h"

void inicializa(stack *p ){
*p = NULL;
}

bool empty(stack p){
if (p==NULL){
return true;
}
else return false;
}

int push(stack * p, Nodo n){
stack nuevo = (stack)malloc(sizeof(Nodo));
if(nuevo == NULL){
return 300;
}
*nuevo = n;
if(empty(*p)){
nuevo->next = NULL;
}
else{
nuevo->next = *p;
*p = nuevo;
}
return 301;
}

Nodo pop(stack * p){
Nodo copy = *(*p);
free(*p);
*p = copy.next;
inicializa(&copy.next);
return copy;
}

Nodo top(stack p){
Nodo copy;
copy = *p;
copy.next = NULL;
return copy;
}
``````

``````struct nodo{
char caracter;
int numero;
struct nodo * next;
};
typedef struct nodo Nodo;
typedef Nodo * stack;
void inicializa(stack *p);
bool empty(stack p);
Nodo top(stack p);
Nodo pop(stack *p);
int push(stack *p, Nodo n);
``````

The short answer -- in this code:

``````int push(stack * p, Nodo n){
stack nuevo = (stack)malloc(sizeof(Nodo));
if(nuevo == NULL){
return 300;
}
*nuevo = n;
if(empty(*p)){
nuevo->next = NULL;
}
else{
nuevo->next = *p;
*p = nuevo;
}
return 301;
}
``````

The `*p = nuevo;` should come after the `else`, not inside it. It applies regardless. The longer answer:

There are several problems with your stack code, including mismanagement of malloc'd memory. I suggest a simpler stack design, along the lines:

``````struct nodo {
char caracter;
struct nodo *next;
};

typedef struct nodo Nodo;
typedef Nodo *stack;

void inicializa(stack *p);
bool empty(stack p);
char top(stack p);
char pop(stack *p);
int push(stack *p, char c);

void inicializa(stack *p) {
*p = NULL;
}

bool empty(stack p) {
return (p == NULL);
}

int push(stack *p, char caracter) {
Nodo *nuevo = malloc(sizeof(*nuevo));

if (nuevo == NULL) {
return 300;
}

nuevo->caracter = caracter;

if (empty(*p)) {
nuevo->next = NULL;
} else {
nuevo->next = *p;
}

*p = nuevo;

return 301;
}

char pop(stack *p) {
Nodo *copy = *p;

*p = copy->next;

char caracter = copy->caracter;

free(copy);

return caracter;
}

char top(stack p) {
return p->caracter;
}
``````

This requires a revision of `revisar()` along the lines:

``````void revisar(char *inf, stack p)
{
char caracter;
char pos[MAX];
int i = 0;
int j = 0;

inicializa(&p);

while (inf[i] != '\0')
{
if (inf[i] >= '0' && inf[i] <= '9')
{
pos[j++] = inf[i++];
}
else if(inf[i] == '(')
{
(void) push(&p, inf[i++]);
}
else if (inf[i] == ')')
{
while (top(p) != '(')
{
pos[j++] = pop(&p);
}

if (top(p) == '(')
{
(void) pop(&p);
}

i++;
}
else
{
if (inf[i] == '+' || inf[i] == '-' || inf[i] == '*' || inf[i] == '/')
{
if (empty(p) || top(p) == '(')
{
(void) push(&p, inf[i++]);

if (empty(p))
{
printf("NNNNNNOOOOOOOOOOOOOOOOOOOOOO"); // Here it prints that the stack is still empty....
}
}
else
{
if (menorpre(top(p), inf[i]))
{
(void) push(&p, inf[i++]);
}
else
{
pos[j++] = pop(&p);

if (!empty(p))
{
if (top(p) != '(')
{
pos[j++] = pop(&p);
}
}
else
{
(void) push(&p, inf[i++]);
}
}
}
}
}
}

while (!empty(p))
{
pos[j++] = pop(&p);
}

pos[j]='\0';

printf("\n \n");
printf("i=%d, j=%d", i, j);
printf("LA CADENA EN POSFIJO ES: ");
puts(pos);
}
``````

In my testing, I was able to get `revisar("1+2", p);` to produce:

``````% ./a.out
ddd

i=3, j=3LA CADENA EN POSFIJO ES: 12+
%
``````

Which I'm guessing is what you're after. If you have more questions about this, make sure to add the definition of `menorpre()` to your code above as it's the piece that's missing that can't be reconstructed.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download