Using a stack to do an infix to postfix - c

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "stack.h"
#define MAX_EQU_LEN 100
static int prec(char operator)
{
switch (operator)
{
case '*':
return 5;
case '/':
return 4;
case '%':
return 3;
case '+':
return 2;
case '-':
return 1;
default:
break;
}
return 0;
}
static int isNumeric(char* num)
{
if(atoi(num) == 0)
{
return 0;
}
return 1;
}
char* infix_to_postfix(char* infix)
{
char* postfix = malloc(MAX_EQU_LEN);
stack* s = create_stack();
s->size = strlen(infix);
node* tempPtr = s->stack;
unsigned int i;
char symbol,next;
char temp[2] = {0};
for(i = 0; i < s->size ; i++)
{
symbol = *((infix + i));
temp[0] = symbol;
tempPtr = s->stack;
if(isNumeric(temp) != 1)
{
strcat(postfix, temp);
}
else if(symbol == '(')
{
push(s, symbol);
}
else if(symbol == ')')
{
while(s->size != 0 && top(s) != '(')
{
next = tempPtr->data;
temp[0] = next;
pop(s);
strcat(postfix, temp);
tempPtr = s->stack;
if(tempPtr->data == '(')
{
pop(s);
}
}
}
else
{
while(s->size != 0 && prec(top(s)) > prec(symbol))
{
next = tempPtr->data;
temp[0] = next;
pop(s);
strcat(postfix,temp);
push(s,next);
}
}
while(s->size != 0)
{
next = tempPtr->data;
temp[0] = next;
pop(s);
strcat(postfix, temp);
}
}
return postfix;
}
int evaluate_postfix(char* postfix) {
//For each token in the string
int i,result;
int right, left;
char ch;
stack* s = create_stack();
node* tempPtr = s->stack;
for(i=0; i < strlen(postfix); i++){
//if the token is numeric
ch = postfix[i];
if(isNumeric(&ch)){
//convert it to an integer and push it onto the stack
atoi(&ch);
push(s, ch);
}
else
{
pop(&s[0]);
pop(&s[1]);
//apply the operation:
//result = left op right
switch(ch)
{
case '+': push(&s[i],right + left);
break;
case '-': push(&s[i],right - left);
break;
case '*': push(&s[i],right * left);
break;
case '/': push(&s[i],right / left);
break;
}
}
}
tempPtr = s->stack;
//return the result from the stack
return(tempPtr->data);
}
This code is part of a bigger program that is designed to convert simple math from infix to postfix and then evaluate it. This will be aided by a stack to hold the numbers and symbols. However when I run the program it seg faults and all the debugger says is that it is in the infix_to_postfix function and I cannot figure out what part of the code makes it seg fault.

Related

I am doing a mini project on stack applications, and get errors

The program:
evaluates postfix and prefix expressions
reverse a string
parenthesis balancing
decimal to binary conversion
infix to postfix conversion
There a some extra characters (emojis) appended in the output. I would like to fix that.
Also I have used two pop functions with int and char return type how can I reduce it to one single function.
extra characters in the output of decimal to binary conversion, also that one extra left parenthesis when printing "balanced parenthesis"
This a first year college project.
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int stack[MAX], opp1, opp2, top = -1;
struct stack
{
char stck[20];
int top;
}
s;
void push(int x)
{
top++;
stack[top] = x;
}
int pop()
{
char c;
c = stack[top];
top = top - 1;
printf("%c", c);
}
char pop1()
{
if (top == -1)
return -1;
else
return stack[top--];
}
void postfixeval()
{
char postfix[20];
int res, i;
gets(postfix);
for (i = 0; postfix[i] != '\0'; i++)
{
if (isdigit(postfix[i]))
{
push(postfix[i] - 48);
}
else
{
opp2 = pop();
opp1 = pop();
switch (postfix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
break;
}
}
}
printf("result is %d \n", pop());
}
void prefixeval()
{
int len;
char prefix[20];
int res, i;
gets(prefix);
len = strlen(prefix);
for (i = len - 1; i >= 0; i--)
{
if (isdigit(prefix[i]))
{
push(prefix[i] - 48);
}
else
{
opp1 = pop();
opp2 = pop();
switch (prefix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
push(res);
break;
}
}
}
printf("result is %d \n", pop());
}
int match(char a, char b)
{
if (a == '[' && b == ']')
return 1;
if (a == '{' && b == '}')
return 1;
if (a == '(' && b == ')')
return 1;
}
int check(char exp[])
{
int i;
char temp;
for (i = 0; i < strlen(exp); i++)
{
if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
push(exp[i]);
if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
if (top == -1)
{
return 0;
}
else
{
temp = pop();
if (!match(temp, exp[i]))
{
printf("Mismatched parentheses are : ");
printf("%c and %c\n", temp, exp[i]);
return 0;
}
}
}
if (top == -1)
{
printf("Balanced Parentheses\n");
return 1;
}
else
{
return 0;
}
}
void dectobin(int n)
{
while (n != 0)
{
push(n % 2);
n = n / 2;
}
while (top != -1)
{
printf("%d", pop());
}
}
int priority(char x)
{
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
}
void intopost()
{
char exp[100];
char *e, x;
printf("Enter the expression : \n");
scanf("%s", exp);
printf("\n");
e = exp;
while (*e != '\0')
{
if (isalnum(*e))
printf("%c ", *e);
else if (*e == '(')
push(*e);
else if (*e == ')')
{
while ((x = pop1()) != '(')
printf("%c ", x);
}
else
{
while (priority(stack[top]) >= priority(*e))
printf("%c ", pop1());
push(*e);
}
e++;
}
while (top != -1)
{
printf("%c ", pop1());
}
}
int main()
{
int ch, i, len;
char postfix[20], prefix[20], str[30];
do {
printf("\n----STACK APPLICATIONS----\n");
printf("1.postfix expression evaluation\n2.prefix expression evaluation\n3.reverse a string\n4.paranthesis balancing\n5.decimal to binary\n6.infix to postfix\n7.exit\n");
printf("enter choice");
scanf("%d", &ch);
switch (ch)
{
case 1:
{
printf("enter postfix expression\n");
scanf("%c", &postfix);
postfixeval();
break;
}
case 2:
{
printf("enter prefix expression\n");
scanf("%c", prefix);
prefixeval();
break;
}
case 3:
{
printf("enter string\n");
scanf("%s", str);
len = strlen(str);
for (i = 0; i < len; i++)
{
push(str[i]);
}
printf("reversed string is:");
for (i = 0; i < len; i++)
{
pop();
}
break;
}
case 4:
{
char exp[20];
int valid;
printf("Enter an algebraic expression : \n");
scanf("%s", exp);
valid = check(exp);
if (valid == 1)
{
printf("Valid expression\n");
}
else
{
printf("Invalid expression\n");
}
break;
}
case 5:
{
int dec;
printf("enter decimal number\n");
scanf("%d", &dec);
dectobin(dec);
break;
}
case 6:
{
intopost();
break;
}
case 7:
{
exit(0);
}
default:
printf("invalid choice\n");
}
} while (ch != 7);
}
Here are the additional characters appended with the output
Here is one 'improvement' that you should learn about 'C'.
printf(
"1.postfix expression evaluation\n"
"2.prefix expression evaluation\n"
"3.reverse a string\n"
"4.paranthesis balancing\n"
"5.decimal to binary\n"
"6.infix to postfix\n"
"7.exit\n"
);
The compiler will 'join-up' those 'segments' (because there is no comma between a close quote and the next open quote.)
Once you have that, you can go back to basics and get this much displaying and functioning:
printf(
// "1.postfix expression evaluation\n"
// "2.prefix expression evaluation\n"
// "3.reverse a string\n"
// "4.paranthesis balancing\n"
// "5.decimal to binary\n"
// "6.infix to postfix\n"
"7.exit\n"
);
Don't try to run before you can walk...
To demonstrate 'incremental development' and 'learning/exploring':
// test.c - string segments in source code
#include <stdio.h>
int main() {
printf(
"Hello "
"World!\n"
);
return 0;
}

RPN with C language

I have problem with this code, It works fine with small values but with big values it crash.
for Example.
input:
1+2+3
output:
Expression:
1+2+3
Reverse Polish Notation:
12+3+
Result:
6
but with this example it crash
input:
100+2*100/50
output:
runtime-error
This code is converting infix to postfix and this calculate the RPN.
// C program to convert infix expression to postfix
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct Stack
{
int top;
unsigned capacity;
int* array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack = (struct Stack*)
malloc(sizeof(struct Stack));
if (!stack)
return NULL;
stack->top = -1;
stack->capacity = capacity;
stack->array = (int*)malloc(stack->capacity *
sizeof(int));
return stack;
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1;
}
char peek(struct Stack* stack)
{
return stack->array[stack->top];
}
char pop(struct Stack* stack)
{
if (!isEmpty(stack))
return stack->array[stack->top--];
return '$';
}
void push(struct Stack* stack, char op)
{
stack->array[++stack->top] = op;
}
int isOperand(char ch)
{
return (ch >= '0' && ch <= '9');
}
int Prec(char ch)
{
switch (ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
int infixToPostfix(char* exp)
{
int i, k;
struct Stack* stack = createStack(strlen(exp));
if (!stack)
return -1;
for (i = 0, k = -1; exp[i]; ++i)
{
if (isOperand(exp[i]))
exp[++k] = exp[i];
else if (exp[i] == '(')
push(stack, exp[i]);
else if (exp[i] == ')')
{
while (!isEmpty(stack) && peek(stack) != '(')
exp[++k] = pop(stack);
if (!isEmpty(stack) && peek(stack) != '(')
return -1;
else
pop(stack);
}
else
{
while (!isEmpty(stack) &&
Prec(exp[i]) <= Prec(peek(stack)))
exp[++k] = pop(stack);
push(stack, exp[i]);
}
}
while (!isEmpty(stack))
exp[++k] = pop(stack);
exp[++k] = '\0';
printf("Reverse Polish Notation:\n");
char str[10];
strcpy(str, exp);
for (int i = 0; str[i]; i++)
{
printf("%c ", str[i]);
}
printf("\n");
}
int evaluatePostfix(char* exp)
{
struct Stack* stack = createStack(strlen(exp));
int i;
if (!stack) return -1;
for (i = 0; exp[i]; ++i)
{
if (isdigit(exp[i]))
push(stack, exp[i] - '0');
else
{
int val1 = pop(stack);
int val2 = pop(stack);
switch (exp[i])
{
case '+': push(stack, val2 + val1); break;
case '-': push(stack, val2 - val1); break;
case '*': push(stack, val2 * val1); break;
case '/': push(stack, val2 / val1); break;
}
}
}
return pop(stack);
}
int main()
{
//char exp[] = "1+2+3";
char exp[10];
scanf("%14s", exp);
printf("Expression:\n%s\n", exp);
infixToPostfix(exp);
printf("Result:\n%d", evaluatePostfix(exp));
return 0;
}

Wrong answer from a program (infix notation->postfix notation) in C

I made a program which changes infix notation to postfix notation with using stack in C.
I made a function which prints the result of the postfix notation(from infix notaton).
But, the result of a notation is wrong. This should be '195' but its result is '-61'.
The results of the other notations are right but only the notation(op2) has this problem.
What should I do to fix this problem?
This is my code:
typedef char element;
typedef struct {
element stack[MAX_STACK_SIZE];
int top;
} StackType;
void init(StackType *s) {
s->top = -1;
}
int is_empty(StackType *s) {
return (s->top == -1);
}
int is_full(StackType *s) {
return (s->top == (MAX_STACK_SIZE - 1));
}
void push(StackType *s, element item) {
if (is_full(s)) {
fprintf(stderr, "FULL STACK ERROR\n");
return;
}
else s->stack[++(s->top)] = item;
}
element pop(StackType *s) {
if (is_empty(s)) {
fprintf(stderr, "EMPTY STACK ERROR\n");
exit(1);
}
else return s->stack[(s->top)--];
}
int eval(char exp[]) {
int op1, op2, value, i = 0;
int len = strlen(exp);
char ch;
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
if (ch != '+' && ch != '-' && ch != '*' && ch != '/') {
value = ch - '0';
push(&s, value);
}
else {
op2 = pop(&s);
op1 = pop(&s);
switch (ch) {
case '+': push(&s, op1 + op2); break;
case '-': push(&s, op1 - op2); break;
case '*': push(&s, op1 * op2); break;
case '/': push(&s, op1 / op2); break;
}
}
}
return pop(&s);
}
char* infix_to_postfix(char exp[]) {
int i = 0, j = 0;
char ch, top_op;
int len = strlen(exp);
char *ex = (char *)malloc(sizeof(char)*(len + 1));
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
switch (ch) {
case '+': case '-': case '*': case '/':
while (!is_empty(&s) && (prec(ch) <= prec(peek(&s)))) {
ex[j++] = pop(&s);
}
push(&s, ch);
break;
case '(':
push(&s, ch);
break;
case ')':
top_op = pop(&s);
while (top_op != '(') {
ex[j++] = top_op;
top_op = pop(&s);
}
break;
default:
ex[j++] = ch;
break;
}
}
while (!is_empty(&s)) {
ex[j++] = pop(&s);
}
ex[j] = NULL;
return ex;
}
void main() {
char *op1 = "(9-(3+2))*3+4*((4+2)/3)-1";
char *op2 = "(4*5-3)/3+((2+5*7)-8+9)*5";
char *op3 = "7*3-7-4+1/3+6-8*2";
char *pos1, *pos2, *pos3;
pos1 = infix_to_postfix(op1);
pos2 = infix_to_postfix(op2);
pos3 = infix_to_postfix(op3);
printf(" Result : %d\n", eval(pos1));
printf(" Result : %d\n", eval(pos2));
printf(" Result : %d\n", eval(pos3));
}
[RESULT]
Result : 19
Result : -61 // This should be '195'.
Result : 0
The clue is 61+195 = 256. Which means that somewhere, your computations are being saved to chars. Looks like it is element.
typedef element int;

Infix to Postfix

I am trying to create a program to convert an infix expression to post fix and evaluate it using a stack. The three files are below. When I run the code I get a segmentation fault. The debugger in Xcode says that it occurs between the push and the two pop calls in the middle file in the evaluate_postfix function. Can anyone help me with why this is seg faulting?
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
stack* create_stack(void)
{
stack* newPtr = malloc(sizeof(stack));
newPtr->size = 0;
newPtr->stack = NULL;
return newPtr;
}
void push(stack *s, int val)
{
node* newPtr = (node*) malloc(sizeof(node));
newPtr->data = val;
newPtr->next = s->stack;
s->stack = newPtr;
s->size++;
}
void pop(stack *s)
{
node* newPtr = NULL;
node* tempPtr = NULL;
tempPtr = s->stack;
newPtr = tempPtr->next;
free(tempPtr);
s->stack = newPtr;
s->size--;
}
int top(stack *s)
{
int num;
node* newPtr = NULL;
newPtr = s->stack;
num = newPtr->data;
return num;
}
int isEmpty(stack *s)
{
if(s->stack == NULL)
{
return 1;
}
else
{
return 0;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "stack.h"
#include <string.h>
#define MAX_EQU_LEN 100
static int prec(char operator)
{
switch (operator)
{
case '*':
return 5;
case '/':
return 4;
case '%':
return 3;
case '+':
return 2;
case '-':
return 1;
default:
break;
}
return 0;
}
static int isNumeric(char* num)
{
if(atoi(num) == 0)
{
return 0;
}
return 1;
}
char* infix_to_postfix(char* infix)
{
int i,a=0;
char* postfix = malloc(MAX_EQU_LEN);
stack* s = create_stack();
for(i=0;infix[i]!='\0';i++){
if(!isNumeric(&((infix[i]))))
{
postfix[a]=infix[i];
a++;
}
else if(isEmpty(s))
push(s,infix[i]);
else if(prec(infix[i])>prec(s->stack->data))
push(s,infix[i]);
else
{
postfix[a]=s->stack->data;
a++;
pop(s);
if(!isEmpty(s)){
while(prec(s->stack->data)<= prec (infix[i]))
{
postfix[a]=s->stack->data;
a++;
pop(s);
}
}
else
push(s,infix[i]);
}
}
return postfix;
}
int evaluate_postfix(char* postfix) {
int i,result = 0;
int right = 0, left = 0;
char* token = NULL;
stack* s = create_stack();
s->size = strlen(postfix);
node* tempPtr = NULL;
for(i = 0; i < s->size ; i++)
{
token = strtok(postfix, " ");
if(isNumeric(token) == 1)
{
atoi(token);
push(s, *token);
}
else
{
left = tempPtr->data;
pop(s);
right = tempPtr->data;
pop(s);
switch(*token)
{
case '+':
result = left + right;
break;
case '-':
result = left - right;
break;
case '*':
result = left * right;
break;
case '/':
result = left / right;
break;
case '%':
result = left % right;
break;
}
push(s, result);
}
strtok(NULL, " ");
}
return result;
}
#include <stdio.h>
#include <string.h>
#include "calculator.h"
#define BUFFERSIZE 100
int main(int argc, char* argv[]) {
char buffer[BUFFERSIZE];
if (argc != 2) {
printf("correct ussage: %s <input file>\n", argv[0]);
return 1;
}
FILE* fp = fopen(argv[0], "r");
if(fp == NULL) {
printf("unable to open file: %s\n", argv[1]);
return 1;
}
while(fgets(buffer, BUFFERSIZE, fp)) {
if (buffer[strlen(buffer)-1] == '\n') {
buffer[strlen(buffer)-1] = '\0';
}
char *postfix = infix_to_postfix(buffer);
int result = evaluate_postfix(postfix);
printf("%s = %d\n", buffer, result);
}
return 0;
}
Each call to strtok() that doesn't contain a NULL pointer as its first argument resets the internal pointer of the strtok() function to the beginning of the string.
At the beginning of the loop in your int evaluate_postfix(char* postfix); function, you call
token = strtok(postfix, " ");
Which means that at the beginning of the loop, token ALWAYS pointers to the first non-space character at the beginning of postfix. So each loop it would see an operator, and try to pop() two values from the stack. But your stack would quickly deplete, and the stack will begin to point to garbage data (s->size < 0).
token = strtok(postfix, " ");
for(i = 0; i < s->size ; i++)
{
....
token = strtok(NULL, " ");
}
Should fix your issue.

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