Infix to postfix implementation using linked lists - c

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.

Related

I am trying to implement bst insertion operations in C by using double pointer but getting a segmentation fault in the code below, idk why?

I think the main problem lies with pointer also keeping in mind the restriction that I can't return node type pointer. Please help me find out where am I doing the mistake.
I have commented the other operations of this code and trying to solve this one first. So the code has switch statements and the irrelevant functions calls have been added as part of comment for now.
#include <stdio.h>
#include <stdlib.h>
typedef struct tree { //definition of structure
int info;
//char *Name;
struct tree *left;
struct tree *right;
} tree;
int main()
{
int flag;
int choice1, item;
char ch;
int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);
tree *root = NULL;
while (1) {
system("clear");
main_menu(&choice1);//calling function to display original menu list
switch (choice1) {
case 1:
printf("\nEnter number to be inserted:");
scanf("%d", &item);
insert(&root, item);
break;
case 2:
//delete();
break;
case 3:
//search();
break;
case 4:
//printf("\nTerminating code.....");
display(root);
//return(1);
break;
default:
printf("\nInvalid choice!!");
break;
}
getchar();
printf("Enter y to continue");
ch = getchar();
if (ch != 'y')
break;
}
return (1);
}
int main_menu(int *choice1) {
printf("\t\tThe main menu of operations are listed below ");//showing menu
printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
printf("\n\nEnter choice:");
scanf("%d", &*choice1);//taking choice of user as input
return (1);
}
tree *getnode(int item) { //function to create node and returning node pointer
tree *p;
p = (tree *)malloc(sizeof(tree));
p->right = NULL;
p->left = NULL;
p->info = item;
return (p);
}
int insert(tree **root, int item) {
tree *ptr, *ptr1, *new;
int flag;
flag = 0;
new = getnode(item);
if (*root == NULL) {
*root = new;
(*root)->left = NULL;
(*root)->right = NULL;
} else {
ptr = *root;
while ((ptr != NULL) && (flag == 0)) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
}
if (ptr->info == item) {
flag = 1;
printf("\nalready present");
return (1);
}
if (item > ptr->info) {
ptr = ptr->right;
}
}
/*if (ptr == NULL) {
new = getnode(item);
}*/
if (ptr1->info < item) {
ptr1->right = new;
} else {
ptr1->left = new;
}
}
return (1);
}
The problem is in the while loop descending the tree: you should add else clauses so the next if test is not evaluated with the updated value of ptr:
while ((ptr != NULL) && (flag == 0)) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
} else
if (ptr->info == item) {
flag = 1;
printf("\nalready present");
return (1);
} else
if (item > ptr->info) {
ptr = ptr->right;
}
}
Note that the flag indicator is redundant as you return directly from the while loop body when you set it to 1.
Note also that the prototypes for the functions called from main should be outside of the body of main so they are visible when the functions are defined and any conflicts can be detected by the compiler.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct tree {
int info;
//char *Name;
struct tree *left;
struct tree *right;
} tree;
int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);
// read and discard the rest of the input line
// return EOF at end of file
int flush_input(void) {
int ch;
while ((ch = getchar()) != EOF && ch != '\n')
continue;
return ch;
}
int main() {
int flag, choice1, item, ch;
tree *root = NULL;
for (;;) {
system("clear");
main_menu(&choice1); //calling function to display original menu list
switch (choice1) {
case 1:
printf("\nEnter number to be inserted: ");
if (scanf("%d", &item) != 1) {
flush_input();
break;
}
flush_input();
insert(&root, item);
break;
case 2:
//delete();
break;
case 3:
//search();
break;
case 4:
//printf("\nTerminating code.....");
display(root);
//return(1);
break;
default:
printf("\nInvalid choice!!");
break;
}
printf("Enter y to continue: ");
/* read and discard the rest of the input line */
ch = getchar();
flush_input()
if (ch != 'y')
break;
}
return 0;
}
int main_menu(int *choice1) {
printf("\t\tThe main menu of operations are listed below ");//showing menu
printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
printf("\n\nEnter choice:");
*choice1 = -1; //default input incase of scanf failure
scanf("%d", choice1); //taking choice of user as input
flush_input(); // discard rest of the line
return 1;
}
tree *getnode(int item) { //function to create node and returning node pointer
tree *p = (tree *)malloc(sizeof(tree));
p->right = NULL;
p->left = NULL;
p->info = item;
return p;
}
int insert(tree **root, int item) {
tree *new, *ptr, *ptr1;
ptr1 = ptr = *root;
while (ptr != NULL) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
} else
if (item > ptr->info) {
ptr = ptr->right;
} else {
printf("\nalready present\n");
return 1;
}
}
new = getnode(item);
if (ptr1 == NULL) {
*root = new;
} else
if (ptr1->info < item) {
ptr1->right = new;
} else {
ptr1->left = new;
}
return 1;
}

Infix to postfix conversion using linked list in c

Can anyone please help me with this code? I'm trying to convert from infix to postfix using a linked list. With an array, I can easily solve this, that solution is also similar to this one. But I'm not getting why this is not working. My guess is I've done anything wrong in this part -
if (precedence(ch) > precedence(top->data))
{
push(ch);
}
else
{
while (precedence(ch) <= precedence(top->data))
{
postfix = insert(postfix, pop());
}
push(ch);
}
Here is the complete code. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
struct Node
{
char data;
struct Node *next;
};
struct Node *top = NULL;
struct Node *postfix = NULL;
void push(char ch);
char pop();
int is_operator(char ch);
int precedence(char ch);
void convert(char *infix);
struct Node *insert(struct Node *head, char ch);
void print(struct Node *head);
int main()
{
char infix[MAX_SIZE] = "(A+B^C)*D+E^5";
printf("Infix: %s\n", infix);
convert(infix);
printf("Postfix: ");
print(postfix);
}
void convert(char *infix)
{
int i, len = strlen(infix);
char ch;
for (i = 0; i < len; i++)
{
ch = infix[i];
if (is_operator(ch) == 0)
{
postfix = insert(postfix, ch);
}
else
{
if (ch == '(')
{
push(ch);
}
else
{
if (ch == ')')
{
while (top->data != '(')
{
postfix = insert(postfix, pop());
}
pop();
}
else
{
if (precedence(ch) > precedence(top->data))
{
push(ch);
}
else
{
while (precedence(ch) <= precedence(top->data))
{
postfix = insert(postfix, pop());
}
push(ch);
}
}
}
}
}
while (top != NULL)
{
postfix = insert(postfix, pop());
}
}
int is_operator(char ch)
{
switch (ch)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '(':
case ')':
return 1;
default:
return 0;
}
}
int precedence(char ch)
{
switch (ch)
{
case '+':
case '-':
return 2;
case '*':
case '/':
return 3;
case '^':
return 4;
default:
return 1; // if (, ), or empty
}
}
void push(char ch)
{
struct Node *newP = (struct Node *)malloc(sizeof(struct Node));
newP->data = ch;
newP->next = top;
top = newP;
}
char pop()
{
char ch = top->data;
struct Node *temp = top;
top = temp->next;
free(temp);
temp = NULL;
return ch;
}
struct Node *insert(struct Node *head, char ch)
{
struct Node *newP = (struct Node *)malloc(sizeof(struct Node));
newP->data = ch;
newP->next = NULL;
if (head == NULL)
{
head = newP;
}
else
{
struct Node *temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newP;
}
return head;
}
void print(struct Node *head)
{
while (head != NULL)
{
printf("%c", head->data);
head = head->next;
}
printf("\n");
}

® (\256) character in c++

what does ® mean in c language and in this codes give an error that [Error] stray '\256' in program in the print part because of ® . And ı
wanna translate c++ code. While that, ım taken [Error] invalid conversion from 'void*' to 'node*' [-fpermissive]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 10
#define EMPTY -1
struct node
{
char kind;
char op;
int number;
struct node *left,*right;
};
struct stack
{
struct node *data[MAX];
int top;
};
int isempty(struct stack *s)
{
return (s->top == EMPTY) ? 1 : 0;
}
void emptystack(struct stack* s)
{
s->top=EMPTY;
}
void push(struct stack* s, struct node *item)
{
if(s->top == (MAX-1))
{
printf("\nSTACK FULL");
}
else
{
++s->top;
s->data[s->top]=item;
}
}
struct node* pop(struct stack* s)
{
struct node *ret=NULL;
if(!isempty(s))
{
ret= s->data[s->top];
--s->top;
}
return ret;
}
void postfix2exptree(char* postfix, struct node **root)
{
struct stack X;
struct node *newnode,*op1,*op2;
char numberextract[5];
char *p;
emptystack(&X);
p = &postfix[0];
strcpy(numberextract,"");
while(*p)
{
while(*p == ' ' || *p == '\t')
{
p++;
}
if(isdigit(*p))
{
while(isdigit(*p))
{
strcat(numberextract,p);
p++;
}
newnode = malloc(sizeof(struct node));
newnode->kind = 'N';
newnode->number = atoi(numberextract);
newnode->left = NULL;
newnode->right = NULL;
push(&X,newnode);
strcpy(numberextract,"");
}
else
{
op1 = pop(&X);
op2 = pop(&X);
newnode = malloc(sizeof(struct node));
newnode->kind = 'O';
newnode->op = *p;
newnode->left = op2;
newnode->right = op1;
push(&X,newnode);
}
p++;
}
*root = pop(&X);
}
int evaluatetree(struct node *x)
{
if( x->kind == 'O' )
{
int op1 = evaluatetree( x->left );
int op2 = evaluatetree( x->right );
switch ( x->op )
{
case '+': return op1 + op2;
case '-': return op1 - op2;
case '*': return op1 * op2;
case '/': return op1 / op2;
default: return 0;
}
}
else
return (x->number);
}
void inorder(struct node *x)
{
if(x != NULL)
{
inorder(x->left);
if(x->kind == 'O')
printf("%c ",x->op);
else
printf("%d ",x->number);
inorder(x->right);
}
}
void preorder(struct node *x)
{
if(x != NULL)
{
if(x->kind == 'O')
printf("%c ",x->op);
else
printf("%d ",x->number);
preorder(x->left);
preorder(x->right);
}
}
void postorder(struct node *x)
{
if(x != NULL)
{
postorder(x->left);
postorder(x->right);
if(x->kind == 'O')
printf("%c ",x->op);
else
printf("%d ",x->number);
}
}
int main()
{
struct node *r;
postfix2exptree("100 50 - 2 /",&r);
printf("Inorder = ");
*inorder®;
printf("\nPreorder = ");
preorder®;
printf("\nPostprder = ");
postorder®;
printf("\nResult = %d\n",evaluatetree®);
return 0;
}
This is an artefact of "smart" text editors.
The code is supposed to read:
inorder(r);
printf("\nPreorder = ");
preorder(r);
where r is a struct node *.
The original author pasted the text and didn't check, smart text editing transformed (r) into the copyright sign.
Note that inorder and preorder are functions defined earlier in the code.

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.

Resources