Evaluate postfix notation - c

I was doing my exercise but i stucked at the last step.
I have to evaluate postfix notation using stacks in C.
Code:
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct
{
int info;
}tipElement;
typedef struct
{
tipElement magacin [MAX];
int vrv;
}tipMagacin;
tipMagacin postfixStack;
void Inicijalizacija(tipMagacin *Mag)
{
(*Mag).vrv = -1; //warehouse is empty
}
int Prazen(tipMagacin Mag)
{
return(Mag.vrv == -1); //returns true if the warehouse is empty
}
int Poln(tipMagacin Mag)
{
return(Mag.vrv == MAX-1); //returns true if the warehouse is full
}
void Push(tipMagacin *Mag, tipElement Element)
{
if (Poln(*Mag)) printf("Warehouse is full\n"); //if it is full report an error
else
{
(*Mag).vrv++; //next position in the warehouse
(*Mag).magacin[(*Mag).vrv].info = Element.info; //put an element
}
}
void Pop(tipMagacin *Mag, tipElement *Element)
{
if (Prazen(*Mag)) printf("Warehouse is empty\n"); //if it is empty report an error
else
{
(*Element).info = (*Mag).magacin[(*Mag).vrv].info; //read the last element
(*Mag).vrv--; // delete it
}
}
int evaluate(int op1, int op2, char operate) {
switch (operate) {
case '*': return op2 * op1;
case '/': return op2 / op1;
case '+': return op2 + op1;
case '-': return op2 - op1;
default : return 0;
}
}
int evaluatePostfix (char *izraz, int n)
{
tipMagacin *Mag;
tipElement element;
tipElement go,z;
int i=0;
int op2;
char ch;
int value;
while (i < n) {
element.info = izraz[i];
if(isdigit(element.info))
{
Push(&postfixStack, element);
}
else
{
z=Pop(&postfixStack, &go);
op2=1;
value = evaluate(z,op2,ch);
Push(Mag,value);
}
i++;
}
return value;
}
my code works fine until here:
else
{
op1=Pop(&postfixStack, &go);
op2=Pop(&postfixStack, &go);
value = evaluate(op1,op2,element.info);
Push(&postfixStack, value);
}
i++;
}
return value;
}
the problem is: error: void value not ignored as it ought to be
my Push and Pop functions are void and i need to put the value that I remove from my stack to some int variable then i calculate them. put it doesnt put it for some reason i dont know.
Anyone help ?

Related

Segmentation fault on assigning int

I am following the video series "Coding a Rogue/Nethack clone in c" and getting a segfault despite the fact that the creator isn't.
This is using ncurses and the menu library.
gdb says it's in the function handleInput, when I try to set the x and y.
Pos* handleInput(int input, Player* user) {
Pos * newPosition;
newPosition = malloc(sizeof(Pos));
switch (input)
{
/* move up */
case 'w':
case 'W':
newPosition->y = user->pos->y - 1;
newPosition->x = user->pos->x;
break;
/* move down */
case 's':
case 'S':
newPosition->y = user->pos->y + 1;
newPosition->x = user->pos->x;
break;
/* move left */
case 'a':
case 'A':
newPosition->y = user->pos->y;
newPosition->x = user->pos->x - 1;
break;
/* move right */
case 'd':
case 'D':
newPosition->y = user->pos->y; // Segfault here
newPosition->x = user->pos->x + 1;
default:
break;
Some typedefs:
typedef struct Level {
int level;
char** tiles;
int numRooms;
struct Player* user;
struct Room** room;
struct Monster** Mons;
int numMons;
} Level;
typedef struct Pos {
int x;
int y;
} Pos;
typedef struct Player {
Pos* pos;
int atk;
int maxHP;
int xp;
int gold;
int health;
} Player;
typedef struct Monster {
char string[2];
char symbol;
int alive;
int health;
int attack;
int speed;
int defense;
int pathfinding;
Pos* pos;
} Monster;
And my game function:
int gameLoop()
{
int ch;
Pos* newPosition;
Level * level;
level = createLevel(1);
Player* user = level->user;
printGameHud(level);
/* main game loop */
while ((ch = getch()) != 'q')
{
printGameHud(level);
newPosition = handleInput(ch, user);
checkPosition(newPosition, level);
moveMonster(level);
move(level->user->pos->y, level->user->pos->x);
if (level->user->health <= 0)
{
return -1;
}
}
return 1;
}
Finally, my menu function, which seems to be where this started:
void menuLoop () {
int choice;
while (true) {
char* choices[] = {"Start", "Exit"};
choice = mainMenu(2, choices);
switch (choice) {
case START_GAME:
gameLoop();
clear();
break;
case QUIT_GAME:
return;
}
}
}
int closeMenu(int numItems, MENU* menu, ITEM** items){
unpost_menu(menu);
free_menu(menu);
for (int i = 0; i < numItems; i++) {
free_item(items[i]);
}
return 1;
}
int mainMenu(int numItems, char* items[]) {
int c, i, value;
MENU* menu;
ITEM* current;
ITEM** menuItems = malloc(sizeof(**menuItems) * numItems);
for (i = 0; i < numItems; i++) {
menuItems[i] = new_item(items[i], "");
}
menuItems[i] = (ITEM*)NULL;
menu = new_menu((ITEM**)menuItems);
post_menu(menu);
refresh();
while (true) {
c = getch();
switch(c){
case KEY_DOWN:
menu_driver(menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(menu, REQ_UP_ITEM);
break;
case 10:
current = current_item(menu);
value = item_index(current);
closeMenu(numItems, menu, menuItems);
return value;
}
}
}

I need help to convert from infix to postfix in C

I was practising some data structures problems that I did previously but this time I don't know what is going wrong in my code. I looked over a long time but I did not found the mistake. When I'm printing I'm just getting the first character and it looks like e is not being updated. But I've written e++.
#include<stdio.h>
#include "ctype.h"
int stack[20];
int top = -1;
void push(int x)
{
stack[++top] = x;
}
int pop()
{
return stack[top--];
}
int priorityof(char x)
{
if(x=='(')
return 3;
else if(x=='+'|| x=='-')
return 1;
else if(x=='*'|| x=='/')
return 2;
}
int main()
{
char exp[20];
char *e;
e=exp;char x;
scanf("%c",exp);
while(*e!='\0')
{
if(isalnum(*e))
{
printf("%c", *e);
}
else if(*e=='(')
{
push(*e);
}
else if(*e==')')
{
while((x=pop())!='(')
printf("%c",x);
}
else {
while (priorityof(stack[top]) >= priorityof(*e)) {
printf("%c", pop());
push(*e);
}
}
e++;
}
while(top!=-1)
{
printf("%c",pop());
}
}
%c is for single character and reading your question it seems like you are giving more than one character so its a string, use %s.
#include<stdio.h>
#include "ctype.h"
int stack[20]; int top = -1;
void push(int x) {
stack[++top] = x;
}
int pop() { return stack[top--]; }
int priorityof(char x) {
if(x=='(') return 3;
else if(x=='+'|| x=='-') return 1;
else if(x=='*'|| x=='/') return 2;
}
int main() {
char exp[20];
char *e;
e=exp;char x;
scanf("%s",exp);
while(*e!='\0') { if(isalnum(*e)) { printf("%c", *e); } else if(*e=='(') { push(*e); } else if(*e==')') { while((x=pop())!='(') printf("%c",x); } else { while (priorityof(stack[top]) >= priorityof(*e)) { printf("%c", pop()); push(*e); } } e++; } while(top!=-1) { printf("%c",pop()); } }

Evaluating a postfix expression using expression tree in C

I can't seem to get this program to work, it is a doubly linked list representation of expression tree. After creating the tree I need to evaluate the result but I can't seem to figure out how.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
char item;
struct node * left;
struct node * right;
}*Btree;
Btree root;
void operandFunc(char);
void operatorFunc(char);
void push(Btree);
Btree pop();
void infix(Btree);
void postfix(Btree);
void prefix(Btree);
int solve(Btree);
int calculate(char,int,int);
int isOperand(char);
char expression[25];
Btree stack[25];
int stackPtr = -1;
int main()
{
int count = 0;
printf("Please enter a postfix expression\n");
while((expression[count++]=getchar())!='\n');
expression[--count] = '\0';
//puts(expression);
for(count = 0;expression[count]!='\0';count++)
{
switch(expression[count])
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(expression[count]);
break;
default:
operandFunc(expression[count]);
}
}
if(stackPtr != 0)
{
printf("Incomplete / Incorrect postfix expression given!\n");
}
else
{
printf("\n\nThe result = %d",solve(stack[stackPtr])+'0');
printf("\n\n");
return 0;
}
}
void prefix(Btree root)
{
Btree temp = root;
if(temp)
{
printf("%c ",temp->item);
prefix(temp->left);
prefix(temp->right);
}
}
void infix(Btree root)
{
Btree temp = root;
if(temp != NULL)
{
infix(temp->left);
printf("%c ",temp->item);
infix(temp->right);
}
}
void postfix(Btree root)
{
Btree temp = root;
if(temp)
{
postfix(temp->left);
postfix(temp->right);
printf("%c ",temp->item);
}
}
void push(Btree root)
{
stack[++stackPtr] = root;
}
Btree pop()
{
return (stack[stackPtr--]);
}
void operandFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item= var;
root->left= NULL;
root->right= NULL;
push(root);
}
void operatorFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item = var;
root->right = pop();
root->left = pop();
push(root);
}
int solve(Btree root)
{
Btree temp = root;
char num1,num2;
char operator;
int result;
if(temp)
{
Btree LEFTP = temp->left;
Btree RIGHTP = temp->right;
if(LEFTP)
{
if(isOperand(LEFTP->item))
{
num1 = LEFTP->item;
}
else
{
num1 = solve(LEFTP);
}
}
if(RIGHTP)
{
if(isOperand(RIGHTP->item))
{
num2 = RIGHTP->item;
}
else
{
num2 = solve(RIGHTP);
}
}
operator = temp->item;
printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2);
result = calculate(operator,num1-'0',num2-'0');
printf("Test Result = %d\n",result);
temp->item = (result+'0');
printf("Root Item = %c and %d\n",temp->item,temp->item);
return result;
}
return NULL;
}
int calculate(char operator,int op1,int op2)
{
printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2);
switch(operator)
{
case '+': return(op1+op2);
break;
case '-': return(op1-op2);
break;
case '*': return(op1*op2);
break;
case '/': return(op1/op2);
break;
case '%': return(op1%op2);
break;
case '$': return pow(op1,op2);
break;
default: printf("\n illegal operation.");
exit;
}
}
int isOperand(char var)
{
switch(var)
{
case '+':
case '-':
case '*':
case '/':
case '$':
case '%':
return 0;
default:
return 1;
}
}
I'm having trouble converting and returning the characters as integers.
UPDATE 1: I was able to make it solve single digit number inputs to recieve a multi digit result. I'm still working on a new data structure to compute multi digit numbers. Here's the updated code below.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
char item;
struct node * left;
struct node * right;
}*Btree;
Btree root;
void operandFunc(char);
void operatorFunc(char);
void push(Btree);
Btree pop();
void infix(Btree);
void postfix(Btree);
void prefix(Btree);
int solve(Btree);
int calculate(char,int,int);
int isOperand(char);
char expression[25];
Btree stack[25];
int stackPtr = -1;
int main()
{
int count = 0;
printf("Please enter a postfix expression\n");
while((expression[count++]=getchar())!='\n');
expression[--count] = '\0';
//puts(expression);
for(count = 0;expression[count]!='\0';count++)
{
switch(expression[count])
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(expression[count]);
break;
default:
operandFunc(expression[count]);
}
}
if(stackPtr != 0)
{
printf("Incomplete / Incorrect postfix expression given!\n");
}
else
{
printf("\n\nThe result = %d",solve(stack[stackPtr])-'0');
printf("\n\n");
return 0;
}
}
void prefix(Btree root)
{
Btree temp = root;
if(temp)
{
printf("%c ",temp->item);
prefix(temp->left);
prefix(temp->right);
}
}
void infix(Btree root)
{
Btree temp = root;
if(temp != NULL)
{
infix(temp->left);
printf("%c ",temp->item);
infix(temp->right);
}
}
void postfix(Btree root)
{
Btree temp = root;
if(temp)
{
postfix(temp->left);
postfix(temp->right);
printf("%c ",temp->item);
}
}
void push(Btree root)
{
stack[++stackPtr] = root;
}
Btree pop()
{
return (stack[stackPtr--]);
}
void operandFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item= var;
root->left= NULL;
root->right= NULL;
push(root);
}
void operatorFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item = var;
root->right = pop();
root->left = pop();
push(root);
}
int solve(Btree root)
{
Btree temp = root;
char num1,num2;
char operator;
int result;
if(temp)
{
Btree LEFTP = temp->left;
Btree RIGHTP = temp->right;
if(LEFTP)
{
if(isOperand(LEFTP->item))
{
num1 = LEFTP->item;
}
else
{
num1 = solve(LEFTP);
}
}
if(RIGHTP)
{
if(isOperand(RIGHTP->item))
{
num2 = RIGHTP->item;
}
else
{
num2 = solve(RIGHTP);
}
}
operator = temp->item;
printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2);
result = calculate(operator,num1-'0',num2-'0');
printf("Test Result = %d\n",result);
temp->item = (result+'0');
printf("Root Item = %c and %d\n",temp->item,temp->item);
return root->item;
}
return NULL;
}
int calculate(char operator,int op1,int op2)
{
printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2);
switch(operator)
{
case '+': return(op1+op2);
break;
case '-': return(op1-op2);
break;
case '*': return(op1*op2);
break;
case '/': return(op1/op2);
break;
case '%': return(op1%op2);
break;
case '$': return pow(op1,op2);
break;
default: printf("\n illegal operation.");
exit;
}
}
int isOperand(char var)
{
switch(var)
{
case '+':
case '-':
case '*':
case '/':
case '$':
case '%':
return 0;
default:
return 1;
}
}
In operandFunc(expression[count]); you are only processing one character. That means you cannot work with multi-character operands like 10 or 123. If these occur, you push each digit separately. So your language is limited to single digit numbers (OK; your decission).
In solve you say printf("Root Item = %c and %d\n",temp->item,temp->item);
. Here, the second argument must be converted to an int: temp->item-'0'. You have to do that whenever you use %d in the printf format.
The rest of your code looks fine. Maybe set a higher warning level when compiling to find more errors?
EDIT/ADDITION:
How to handle multi-digit numbers?
The following snippet handles multi-digit numbers. You must adapt your struct to make a difference between chars and ints and change operandFunc to handle these numbers:
while((c=getchar())!='\n')
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(c);
break;
default: // assume digit(s)
num= c-'0';
while ((c=getchar())!='\n' && isdigit(c)) num= num*10+c-'0';
operandFunc(num);
ungetc(c,stdin);
}
}
We can evaluate the postfix expression using the binary tree by keeping in mind the two conditions
if
eval(root) is an operator we use recursion, eval(root->llink) + eval(root->rlink)
else
we return root->info - '0'
Function for evaluation
float evaluate(NODE root)
{
float num;
switch(root->info)
{
case '+' : return eval(root->llink) + eval(root->rlink);
case '-' : return eval(root->llink) - eval(root->rlink);
case '/' : return eval(root->llink) / eval(root->rlink);
case '*' : return eval(root->llink) * eval(root->rlink);
case $ :
case ^ : return pow( eval(root->llink) ,eval(root->rlink));
default : if(isalpha(root->info))
{
printf("%c" = root->info);
scanf("%f",&num);
return num;
}
else
return root->info - '0';
}
}

infix to postfix using stack error in updating top variable

I'm trying to implement a code for infix to postfix conversion but I'm not able to obtain the output. By analyzing the program I found that the variable top s not getting updated even though I'm returning its value back to the main. Please help me figure it out. The code is:
#include<stdio.h>
char stack[15];
int check(char op)
{
int rank=0;
switch(op)
{
case '/':
rank=1;
break;
case '*':
rank=2;
break;
case '+':
rank=3;
break;
case '-':
rank=4;
break;
}
return rank;
}
int POP(char stack[15],int top)
{
if(top==-1)
{
printf("Stack Underflow");
return top;
}
else
{
top--;
printf("%c",stack[top+1]);
return top;
}
}
int PUSH(char stack[15],int top,char op)
{
char opstack;
int rank1,rank2;
if(top>=14)
{
printf("Stack Overflow");
return top;
}
else
{
if(top==-1)
{
top++;
stack[top]=op;
return top;
}
else
{
opstack=stack[top];
rank1=check(op);
rank2=check(opstack);
if( rank1 <= rank2 )
{
top++;
stack[top]=op;
}
else
{
top=POP(stack,top);
top=PUSH(stack,top,op);
}
return top;
}
}
}
int main()
{
char string[15],ch;
int top=-1,i;
printf("Enter the infix operation: ");
gets(string);
fflush(stdin);
for(i=0;string[i]!='\0';i++)
{
ch=string[i];
if( ((ch>='a') && (ch<='z'))||((ch>='A') &&(ch<='Z')) )
{
printf("%c",string[i]);
}
else
{
ch=string[i];
top=PUSH(stack,top,ch);
}
top=POP(stack,top);
}
return 0;
}
in main function add these three lines after for loop End.and remove top=POP(stack,top);
inside for loop.
while(top!=-1)
top=POP(stack,top);
printf("\n");
modified main function:
int main()
{
char string[15],ch;
int top=-1,i;
printf("Enter the infix operation: ");
gets(string);
fflush(stdin);
for(i=0;string[i]!='\0';i++)
{
ch=string[i];
if( ((ch>='a') && (ch<='z'))||((ch>='A') &&(ch<='Z')) )
{
printf("%c",string[i]);
}
else
{
ch=string[i];
top=PUSH(stack,top,ch);
}
}
while(top!=-1)
top=POP(stack,top);
printf("\n");
return 0;
}

Infix to postfix implementation using linked lists

I've been trying to debug this program for a long time. It works fine when I input expressions like a + b - c or a / b + c where the first operator has a greater or equal precedence than the second. But for expressions like a - b / c where the first operator has a lesser precedence than the second, the compiler throws a breakpoint.
struct stack
{
char ele;
struct stack *next;
};
void push(int);
int pop();
int precedence(char);
struct stack *top = NULL;
int main()
{
char infix[20], postfix[20];
int i = 0, j = 0;
printf("ENTER INFIX EXPRESSION: ");
gets(infix);
while(infix[i] != '\0')
{
if(isalnum(infix[i]))
postfix[j++] = infix[i];
else
{
if(top == NULL)
push(infix[i]);
else
{
while( top != NULL &&
(precedence(top->ele) >= precedence(infix[i])) )
postfix[j++]=pop();
push(infix[i]);
}
}
++i;
}
while(top != NULL)
postfix[j++] = pop();
postfix[j] = '\0';
puts(postfix);
getchar();
return 0;
}
int precedence(char x)
{
switch(x)
{
case '^': return 4;
case '*':
case '/': return 3;
case '+':
case '-': return 2;
default: return 0;
}
}
void push(int x)
{
int item;
struct stack *tmp;
if(top == NULL)
{
top = (struct stack *)malloc(sizeof(struct stack));
top->ele = x;
top->next = NULL;
}
else
{
tmp = top;
top->ele = x;
top->next = tmp;
}
}
int pop()
{
struct stack *tmp;
int item;
if(top == NULL)
puts("EMPTY STACK");
else if(top->next == NULL)
{
tmp = top;
item = top->ele;
top = NULL;
free(tmp);
}
else
{
tmp = top;
item = top->ele;
top = top->next;
free(tmp);
}
return item;
}
Any advice on how to improve my coding would be helpful.

Resources