RPN with C language - c

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;
}

Related

I am trying to make a function to convert from prefix to infix implementation in C

I am trying to make a function to convert from prefix to infix implementation in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define type char* //type of element in the stack
#define max 100
typedef struct {
int top;
type array[max];
} stack;
stack *initialize() {
stack *s = malloc(sizeof(stack));
if (!s)
return NULL;
s->top = 0;
return s;
}
void push(stack *s, type x) {
s->array[s->top++] = x;
}
type pop(stack *s) {
return s->array[--s->top];
}
type isfull(stack *s) {
return s->top >= max;
}
type isempty(stack *s) {
return !s->top;
}
type peek(stack *s) {
return s->array[s->top - 1];
}
int isoperator(char *x) {
if (x[0] == '+' || x[0] == '*' || x[0] == '/' || x[0] == '-' || x[0] == '^')
return 1;
else
return 0;
}
void error() {
printf("error");
exit(-1);
}
char *prefix_to_infix(char *pre) {
char op1[20], op2[20], temp[2];
char *fin = malloc(30);
stack *s = initialize();
int i;
for (i = strlen(pre) - 1; i >= 0; i--) {
temp[0] = pre[i];
temp[1] = '\0';
if (temp[0] == ' ')
continue;
if (temp[0] >= '0' && temp[0] <= '9') {
push(s, temp);
} else
if (isoperator(temp)) {
if (!isempty(s)) {
strcpy(op1, pop(s));
} else
error();
if (!isempty(s)) {
strcpy(op2, pop(s));
} else
error();
strcpy(fin, "(");
strcat(fin, op1);
strcat(fin, temp);
strcat(fin, op2);
strcat(fin, ")");
push(s, fin);
}
}
if (isempty(s))
error;
strcpy(fin, pop(s));
return fin;
}
int main() {
char *s = prefix_to_infix("-78");
printf("%s", s);
return 0;
}
The output should be (7-8) but the output is (---)
when I pop from the stack it gives '-' I don't know how because I only push numbers in the stack
When you push a string with push(s, temp); or push(s, fin); only the pointer gets copied to the stack. The array it points to gets overwritten by the next token or the next string composed using strcpy and strcat.
You should allocate a copy of the string.
Here is a modified version:
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STACK_SIZE 100
typedef struct {
int top;
char *array[STACK_SIZE];
} stack;
stack *initialize(void) {
stack *s = malloc(sizeof(stack));
if (!s)
return NULL;
s->top = 0;
return s;
}
void push(stack *s, const char *x) {
assert(s->top < STACK_SIZE);
s->array[s->top++] = strdup(x);
}
char *pop(stack *s) {
assert(s->top > 0);
return s->array[--s->top];
}
int isfull(const stack *s) {
return s->top >= STACK_SIZE;
}
int isempty(const stack *s) {
return !s->top;
}
char *peek(const stack *s) {
assert(s->top > 0);
return s->array[s->top - 1];
}
int isoperator(const char *x) {
return (x[0] == '+' || x[0] == '*' || x[0] == '/' || x[0] == '-' || x[0] == '^');
}
void error(void) {
printf("error");
exit(-1);
}
char *prefix_to_infix(const char *pre) {
stack *s = initialize();
int i = strlen(pre);
while (i --> 0) {
char temp[2], buf[80];
temp[0] = pre[i];
temp[1] = '\0';
if (isspace((unsigned char)temp[0]))
continue;
if (temp[0] >= '0' && temp[0] <= '9') {
push(s, temp);
} else
if (isoperator(temp)) {
char *op1 = NULL, *op2 = NULL;
if (!isempty(s)) {
op1 = pop(s);
} else {
error();
}
if (!isempty(s)) {
op2 = pop(s);
} else {
error();
}
snprintf(buf, sizeof buf, "(%s%s%s)", op1, temp, op2);
free(op1);
free(op2);
push(s, buf);
} else {
printf("syntax error at '%s'\n", temp);
}
}
if (isempty(s)) {
error();
}
return pop(s);
}
int main() {
char *s = prefix_to_infix("-78");
printf("%s\n", s);
free(s);
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;

Using a stack to do an infix to postfix

#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.

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