I'm writing code to convert Infix expression into Postfix and Prefix at the same time.
My problem is I haven't been able to convert into the prefix expression. In my intoprefix() I tried everything, but still the output will same as to the postfix.
Where if i input this expression
A+B
The expected output would be
Postfix expression is: AB+
Prefix expression is: +AB
but my output is
Postfix expression is: AB+
Prefix expression is: AB+AB+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stack{
char data;
struct Stack *next;
}*top = NULL, *pstart = NULL;
char str[50];
int main(int argc, char **argv){
printf("Enter infix expression: ");
gets(str);
printf("\n\nEquivalent postfix expression is: ");
intopostfix(str);
printf("\n\nEquivalent prefix expression is: ");
intoprefix(str);
printf("\n");
return 0;
}
/* function for insert operation */
void insert(char ch){
struct Stack *ptr,*newNode;
newNode = (struct Stack *)malloc(sizeof(struct Stack));
newNode->next = NULL;
newNode->data = ch;
ptr = pstart;
if(pstart == NULL){
pstart = newNode;
}
else{
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = newNode;
}
}
/* function for push operation */
void push(char symbol){
struct Stack *ptr;
ptr = (struct Stack *)malloc(sizeof(struct Stack));
ptr->data = symbol;
if(top == NULL){
top = ptr;
ptr->next = NULL;
}
else{
ptr->next = top;
top = ptr;
}
}
char pop(){
struct Stack *ptr1;
char ch1;
if(top == NULL){
printf("Stack underflow\n");
return 0;
}
else{
ptr1 = top;
top = top->next;
ch1 = ptr1->data;
free(ptr1);
ptr1 = NULL;
return ch1;
}
}
/* function for display display operation */
void displaypost(){
struct Stack *temp;
if(pstart == NULL)
printf("");
else{
temp = pstart;
while(temp != NULL){
printf("%c",temp->data);
temp = temp->next;
}
}
}
/*function for precedence */
int precedence(char ch){
if(ch == '^'){
return (5);
}
else if(ch == '*' || ch == '/'){
return (4);
}
else if(ch == '+' || ch == '-'){
return (3);
}
else{
return (2);
}
}
/*function for converting infix to postfix */
void intopostfix(char str[]){
int length;
int index = 0;
char symbol, temp;
length = strlen(str);
while(length > index)
{
symbol = str[index];
switch(symbol){
case '(':
push(symbol);
break;
case ')':
temp = pop();
while(temp != '('){
insert(temp);
temp = pop();
}
break;
case '^':
case '+':
case '-':
case '*':
case '/':
if(top == NULL){
push(symbol);
}
else{
while(top != NULL && (precedence(top->data) >= precedence(symbol))){
temp = pop();
insert(temp);
}
push(symbol);
}
break;
default:
insert(symbol);
}
index = index + 1;
}
while(top != NULL){
temp = pop();
insert(temp);
}
displaypost();
return;
}
/*function to convert infix to prefix */
void intoprefix(char str[]){
int length;
int index = 0;
char symbol, temp;
length = strlen(str);
while(length > index)
{
symbol = str[index];
switch(symbol){
case ')':
temp = pop();
break;
case '(':
push(symbol);
while(temp != ')'){
insert(temp);
temp = pop();
}
break;
case '+':
case '-':
case '*':
case '/':
case '^':
if(top == NULL){
push(symbol);
}
else{
while(top != NULL && (precedence(top->data) <= precedence(symbol))){
temp = pop();
insert(temp);
}
push(symbol);
}
break;
default:
insert(symbol);
}
index = index + 1;
}
while(top != NULL){
temp = pop();
insert(temp);
}
displaypost();
return;
}
The program converts infix to postfix and prefix using linked lists (stacks)
Here are my observations and amendments:
Received a warning about gets. Have used fgets instead.gets is
dangerous as it may cause a buffer overflow.
Freed the storages allocated in the insert function.The presence of
these locations were causing the duplication of results,when
intoprefix was called.
Since you already have an intopostfix function, I utilized the same
to convert infix to prefix using the following algorithm. Please
refer.
Step 1:Reverse the infix expression. Note while reversing each ‘(‘ will
become ‘)’ and each ‘)’ becomes ‘(‘.
Step 2:Obtain the postfix expression of the modified expression.
Step 3:Reverse the postfix expression.
Made main the owner of the arrays that store the input and results, thus avoiding the use of "global variables" and requiring me to pass these variables explicitly.
Removed the displaypost function from within intopostfix and am
calling it from main.
void insert(char ch);//no changes made
void push(char symbol); //no changes made
char pop(); //no changes made
void displaypost(char * s);
int precedence(char ch); //no changes made
void intopostfix(char str[]); //removed the call to displaypost
int main(int argc, char **argv){
char str[50];
char prefix_str[50];//store postfix str
char postfix_str[50];//store prefix str
printf("Enter infix expression: ");
fgets(str,50,stdin);
str[strlen(str)-1] = '\0';//overwrite newline char with NULL
//reverse the original string and store in prefix_str
int i,j;
for(i = strlen(str)-1,j = 0;i >= 0;i--,j++){
if(str[i] == '(')
prefix_str[j] = ')';
else if(str[i] == ')')
prefix_str[j] = '(';
else
prefix_str[j] = str[i];
}
prefix_str[j] = '\0';
//Print Post Fix
printf("\n\nEquivalent postfix expression is: ");
intopostfix(str);
displaypost(postfix_str);
printf("%s",postfix_str);
//Print Prefix
intopostfix(prefix_str);
displaypost(prefix_str);
//reverse prefix_str
int temp;
for(i = 0,j = strlen(prefix_str)-1;i < j;i++,j--){
temp = prefix_str[i];
prefix_str[i] = prefix_str[j];
prefix_str[j] = temp;
}
printf("\n\nEquivalent prefix expression is: ");
printf("%s\n",prefix_str);
printf("\n");
return 0;
}
//changes in displaypost
void displaypost(char * s){
struct Stack *temp,*p;
if(pstart == NULL)
printf("");
else{
temp = pstart;
int i = 0;
while(temp != NULL){
p = temp;
s[i] = temp->data;//store character in array
temp = temp->next;
free(p);//free storage
i++;
}
s[i] = '\0';
}
pstart = NULL;
}
Related
I'm trying to implement a stack in C to convert infix to postfix. But after several days of trying, im still not sure whats wrong with my code! can someone help? I made sure the line of logic is right and did on paper a lot of times, I'm new to stack, please assist!
I'm not sure exactly where is going wrong, and after a few submissions, suddenly the same code would produce segmentation error (core dumped) without much explanation.
Examples of inputs like : (A+B)+(C-D) produces (AB)+(C+D)- As for debuggers, im sticking to simple print statements at various parts of the program, I find that theres a problem with popping the '(' at the else if (infix == ')')
Running the code in online IDEs like replit and codechef. replit produces segmentation fault(core dumped) while codechef is able to produce and run an output. <- abit confused here
EDIT: My parenthesis Else if statements arent working, but I dont see why so, I tried adding simple print statements in that else if segments but they are not showing too
#include <stdio.h>
#include <stdlib.h>
#define SIZE 1000 //The limit of expression length
typedef struct _stackNode{
char item;
struct _stackNode *next;
}StackNode;
typedef struct _stack{
int size;
StackNode *head;
}Stack;
void push(Stack *sPtr, char item);
int pop(Stack *sPtr);
char peek(Stack s);
int isEmptyStack(Stack s);
void in2Post(char*, char*);
int main()
{
char infix[SIZE];
char postfix[SIZE];
printf("Enter an infix expression:\n");
scanf("%[^\n]%*c",infix);
printf("This");
in2Post(infix,postfix);
printf("The postfix expression is \n");
printf("%s\n",postfix);
return 0;
}
void push(Stack *sPtr, char item){
StackNode *newNode;
newNode = (StackNode *) malloc(sizeof(StackNode));
newNode->item = item;
newNode->next = sPtr->head;
sPtr->head = newNode;
sPtr->size++;
}
int pop(Stack *sPtr){
if(sPtr == NULL || sPtr->head == NULL){
return 0;
}
else{
StackNode *temp = sPtr->head;
sPtr->head = sPtr->head->next;
free(temp);
sPtr->size--;
return 1;
}
}
char peek(Stack s){
return s.head->item;
}
int isEmptyStack(Stack s){
if(s.size == 0) return 1;
else return 0;
}
int precedence(char item)
{
if (item == '*' || item == '/')
{
return 2;
}
else if (item == '+' || item == '-')
{
return 1;
}
else
{
return 0; // if it is brackets return 0
}
}
int isOperand(char ch)
{
if (ch == '%' || ch == '/' || ch == '*' || ch == '+' || ch == '-')
{
return 0;
}
else
{
return 1;
}
}
int is_operator(char item)
{
if (item == '+' || item == '-' || item == '*' || item == '/')
{
return 1;
}
else
{
return 0;
}
}
void in2Post(char* infix, char* postfix)
{
//Write your code here
Stack* stack = (Stack*)malloc(sizeof(Stack));
stack->head = NULL;
if (!stack)
return;
int i = 0;
int j = 0;
while (infix[i] != '\0')
{
if (isOperand(infix[i]) && infix[i] != ')' && infix[i] != '(') //NEED TO MAKE SURE HERE ISNT A PARENTHESIS
{
postfix[j]=infix[i];
j++;
}
else if (infix[i] == '(')
{
push(stack, infix[i]);
}
else if (infix[i] == ')')
{
while (!isEmptyStack(*stack) && peek(*stack) != '(')
{
postfix[j] = peek(*stack);
j++;
pop(stack);
if (!isEmptyStack(*stack) && peek(*stack) !='(' )
{
return; // POPPING TILL REACH '(' IF IT IS NOT '(', RETURN
}
else
{
pop(stack); // removing the ()
}
}
}
else // an OPERATOR IS ENCOUNTERED
{
while (!isEmptyStack(*stack) && precedence(infix[i])<=precedence(peek(*stack)))
{
postfix[j] = peek(*stack);
pop(stack);
j++;
}
push(stack, infix[i]);
}
i++;
}
while (!isEmptyStack(*stack))
{
postfix[j] = peek(*stack);
pop(stack);
j++;
}
postfix[j] = '\0';
printf("THIS IS POSTFIX %s\n", postfix);
}
The first IF statement did not take into account the character might be a parenthesis. Also, the size of the stack is not initialized.
I am trying to write a program to check if a string of brackets is balanced or not. If balanced, I do not want any output. But if it is not balanced then I want it to return the brackets needed to balance it. For example '([])' should be balanced and '({}' should be unbalanced and should return "open: )". The code seems to work fine until I have two or more brackets left open. So if I input '({' my code works but when I add a few more characters like '([])([' it fails because of a stack overflow. I do not understand what the error could be or how to fix it.
Here is my code:
void push(struct sNode** top_ref, int new_data){
struct sNode* new_node = (struct sNode*)malloc(sizeof(struct sNode));
if (new_node == NULL) {
printf("Stack overflow \n");
getchar();
exit(0);
}
new_node->data = new_data;
new_node->next = (*top_ref);
(*top_ref) = new_node;
}
int pop(struct sNode** top_ref){
char res;
struct sNode* top;
if (*top_ref == NULL) {
printf("Stack overflow \n");
getchar();
exit(0);
}else {
top = *top_ref;
res = top->data;
*top_ref = top->next;
free(top);
return res;
}
}
// Returns 1 if character1 and character2 are matching left and right Brackets
bool isMatchingPair(char character1, char character2)
{
if (character1 == '(' && character2 == ')')
return 1;
else if (character1 == '{' && character2 == '}')
return 1;
else if (character1 == '[' && character2 == ']')
return 1;
else
return 0;
}
// Return 1 if expression is balanced
int areBracketsBalanced(char exp[]){
int i = 0;
struct sNode* stack = NULL;
while (exp[i]){
if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[')
push(&stack, exp[i]);
if (exp[i] == '}' || exp[i] == ')' || exp[i] == ']') {
if (stack == NULL){
printf("%d:%c\n",i,exp[i]);
return 0;
}else if (!isMatchingPair(pop(&stack), exp[i])){
printf("%d:%c\n",i,exp[i]);
return 0;
}
}
i++;
}
if (stack != NULL){
printf("open: ");
while(stack!=NULL){
if(pop(&stack)=='('){
printf("%c",')');
}else if(pop(&stack)=='['){
printf("%c",']');
}else if(pop(&stack)=='{'){
printf("%c",'}');
}
}
printf("\n");
return 0;
}
return 0;
}
int main(int argc, char* argv[])
{
char *exp = (char *)malloc(strlen(argv[1]) * sizeof(char));
for(int i = 0; i<strlen(argv[1]); i++){
exp[i] = argv[1][i];
}
//char exp[] = "([])([";
areBracketsBalanced(exp);
return 0;
}
As it has been pointed out in comments, your exp in main is wrong as it end up without a zero termination. Actually there is no need for it... just pass argv[1] to the function.
int main(int argc, char* argv[])
{
if (argc > 1)
{
areBracketsBalanced(argv[1]);
}
else
{
puts("Missing argument");
}
return 0;
}
Besides that, you have a problem here:
while(stack!=NULL){
if(pop(&stack)=='('){
printf("%c",')');
}else if(pop(&stack)=='['){
printf("%c",']');
}else if(pop(&stack)=='{'){
printf("%c",'}');
}
}
Each of these pop(&stack) will change stack and maybe cause it to be NULL. At worst you do 3 pop-operations before checking for NULL. That's not good.
Change the code so that you have one pop operation before the if statements. Save the result in a local variable that you use for the if statement. Like:
while(stack!=NULL){
int value = pop(&stack);
if(value == '('){
printf("%c",')');
}else if(value == '['){
printf("%c",']');
}else if(value == '{'){
printf("%c",'}');
}
}
I have implemented a trie data structure (reference). When I insert into the data structure, I get a segmentation fault. It could be a semantic error. Please help to correct it.
#include <stdio.h>
#include <stdlib.h>
#define maxlength 10
typedef struct node {
int isend;
struct node *branch[27];
} trinode;
int count, len;
trinode *createnode() {
trinode *new = (trinode *)malloc(sizeof(trinode));
int ch;
for (ch = 0; ch < 26; ch++) {
new->branch[ch] = NULL;
}
new->isend = 0;
}
trinode *insert_trie(trinode *root, char *newenty) {
int ind;
trinode *proot;
if (root == NULL)
root = createnode();
proot = root;
for (int i = 0; i < maxlength; i++) {
ind = newenty[i] - 'a';
if (newenty[i] == '\0')
break;
else {
if (root->branch[ind] == NULL)
root->branch[ind] = createnode();
root = root->branch[ind];
}
if (root->isend != 0)
printf("trying to insert duplicate");
else
root->isend = 1;
return proot;
}
}
void print_trie(trinode *cur) {
char word[40];
for (int i = 0; i < 26; i++) {
if (cur->branch[i] != NULL) {
word[count++] = (i + 'a');
if ((cur->branch[i]->isend) == 1) {
printf("\n");
for (int j = 0; j < count; j++) {
printf("%c", word[j]);
}
}
print_trie(cur->branch[i]);
}
}
count--;
}
int search_trie(trinode *root, char *target) {
int ind;
for (int i = 0; i < maxlength && root; i++) {
ind = target[i] - 'a';
if (target[i] == '\0')
break;
else
root = root->branch[ind];
}
if (root && root->isend == 1)
return root;
else
return 0;
}
int main() {
int ch;
trinode *root = NULL;
char *newenty;
char *target;
int check;
while (1) {
printf("\n enter option 1.insert_trie 2.display 3.search 4.exit");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("enter word");
scanf("%s", newenty);
root = insert_trie(root, newenty);
break;
case 2:
count = 0;
print_trie(root);
break;
case 3:
printf("enter elem you want to search");
scanf("%s", target);
check = search_trie(root, target);
if (check == 0)
printf("word not found");
else
printf("found");
break;
case 4:
exit(0);
break;
}
}
}
For starters the function createnode returns nothing
trinode *createnode()
{
trinode *new=(trinode *)malloc(sizeof(trinode));
int ch;
for(ch=0;ch<26;ch++)
{
new->branch[ch]=NULL;
}
new->isend=0;
}
Also it is unclear why the condition in the for loop is ch<26 instead of ch < 27 while the data member branch has 27 elements
struct node *branch[27];
This for in the function insert_trie
for(int i=0;i<maxlength;i++)
does not make a sense because within the loop there is the return statement
return proot;
So the loop has no more than one iteration.
The function print_trie depends on the global variable count that is a very bad design and it is unclear what the function does.
The function search_trie is declared like
int search_trie(trinode *root,char *target)
That is it has the return type int. However the function returns a pointer of the type trinode*:
if(root && root->isend==1)
return root;
In main the pointers
char *newenty;
char *target;
are not initialized and have indeterminate values. Thus these statements
scanf("%s",newenty)
and
scanf("%s",target);
invoke undefined behavior.
And you need to format the text of the program. A bad formatting is usually a reason of bugs.
char *newenty;
….
scanf("%s",newenty);
root=insert_trie(root,newenty);
newenty isn't pointing to valid memory, allocate memory to it like below.
char *newenty = malloc(maxLength);
I'm making a regex parser. The instruction "t->left = tmp;" the instruction "t->left = tmp;" creates a segmentation fault, but not always ! Try executing the code several times, you'll see that it doesn't always happen. The segmentation fault occurs when printing the tree, because one of the nodes has a child with address "0x62" or "0x54" or something similar. It's really weird because when "tmp" is created I check that both children are NULL but somehow one of them gets modified to "0x.." while executing.
Thanks to anyone that could help me solve this !
I spent quite a while trying to figure out why just adding a "left children" while parsing the tree will create a segmentation fault. I really don't understand because it's a simple pointer creation and assignment ! Comment the instruction "t->left = tmp;" and the segmentation fault is gone ! The weirdest issue so far..
Best regards !
/*
* Includes
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Typedefs
*/
struct node {
char val;
struct node* left;
struct node* right;
};
typedef struct node NODE;
typedef struct node * TREE;
/*
* Tree handling
* - create
* - free
* - print
*/
TREE createNode(char val) {
TREE t = (TREE) malloc(sizeof(TREE));
t->val = val;
t->left = NULL;
t->right = NULL;
return t;
}
void freeTree(TREE t) {
if (t != NULL) {
if (t->left != NULL)
freeTree(t->left);
if (t->right != NULL)
freeTree(t->right);
free(t);
}
}
void printNode(TREE t) {
printf("------ NODE ------\n");
printf("t == %p\n", t);
if (t != NULL) {
printf("val = %c\n", t->val);
printf("left : %p\n", t->left);
printf("right : %p\n", t->right);
}
}
void printTree(TREE t) {
if (t != NULL) {
printf("%c\t[%p]\n", t->val, t);
printf("%p\n", t->left);
if (t->left != NULL) {
printf("----------------begin left----------------\n");
printTree(t->left);
printf("----------------end left----------------\n");
}
printf("%p\n", t->right);
if (t->right != NULL) {
printTree(t->right);
}
}
}
/*
* Misc functions
*/
char* concat(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
//in real code you would check for errors in malloc here
strcpy(result, s1);
strcat(result, s2);
return result;
}
char* substr(char* s, int start) {
int i = 0;
char* sub = malloc(4*(strlen(s) - start) + 1); // +1 for the zero-terminator
while (s[i+start] != '\0') {
sub[i] = s[i+start];
i++;
}
return sub;
}
char* substr_(char* s, int start, int end) {
int i = 0;
char* sub = malloc(4*(strlen(s) - start) + 1); // +1 for the zero-terminator
while (s[i+start] != '\0' && i < (end-start+1)) {
sub[i] = s[i+start];
i++;
}
return sub;
}
/*
* Regex handling
*/
TREE parseParenthesis(char* regex) {
if (regex[0] == '\0') return NULL;
printf("%s\n",regex);
TREE tree = createNode(regex[0]);
int i = 0;
int start = 1;
int lastParenthesisPos = 0;;
switch (regex[0]) {
case '(' :
while (regex[i] != '\0') {
if (regex[i] == ')')
lastParenthesisPos = i;
i++;
}
tree->left = parseParenthesis(substr_(regex, 1, lastParenthesisPos-1));
start = lastParenthesisPos + 1;
break;
case '|' :
case ')' : // Handled by case ')'
case '*' :
case '+' :
case '?' :
default : break;
}
tree->right = parseParenthesis(substr(regex, start));
return tree;
}
void parseExtras(TREE t, TREE parent) {
if (t == NULL) return;
TREE tmp = NULL;
switch (t->val) {
case '*' :
case '+' :
case '?' :
parseExtras(t->right, t);
tmp = createNode(parent->val);
t->left = tmp;
break;
case '(' :
case ')' :
case '|' :
default :
parseExtras(t->left, t);
parseExtras(t->right, t);
break;
}
}
/*
* Main
*/
int main() {
//char* regex = "a|(b|c*)?d|ef";
char* regex = "ab*dd*";
// Parse ()
TREE t = parseParenthesis(regex);
printf("************************************ OK - Parse parenthesis\n");
// Parse * + ?
parseExtras(t, NULL);
printf("************************************ OK - Parse extras\n");
printTree(t);
printf("************************************ OK - Print tree\n");
freeTree(t);
printf("************************************ OK - Free tree\n");
return 0;
}
You are allocating space only for a pointer, not the actual struct:
TREE t = (TREE) malloc(sizeof(TREE));
After this, you are modifying memory that is beyond the size of TREE (which is a pointer).
As a comment above said, don't use typedef unnecessarily.
For a component of an assignment for college we have to implement a stack, which I think I've done well enough for it to be functional. When I'm testing the stack by itself it seems to work fine, however when I'm using it as part of my solution it behaves differently, and I can't figure out why. Can someone please point out my mistake? Thanks.
Edit: I can feel a lot of "how does it behave differently?" comments are on the way, so here's what I've noticed. When running the Testing stack section of main, all the operations execute and print perfectly fine, but when I'm running the second part of main and comment out the testing part instead, the program crashes when I'm trying to push onto the stack - something that didn't fail previously.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct stackNode {
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
typedef enum {
false, true
} t_bool;
void* emalloc(size_t s) {
void* p = malloc(s);
if (NULL == p) {
fprintf(stderr, "Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
return p;
}
void print_array(char* array, size_t n){
int i;
printf("[");
for(i = 0; i < n - 1; i++){
printf("%c, ", array[i]);
}
printf("%c]\n", array[i]);
}
// Determine if c is an operator.
int isOperator(char c) {
char ops [6] = {'+', '-', '*', '/', '%', '^'};
int i;
for (i = 0; i < 6; i++)
if (ops[i] == c) return true;
return false;
}
int op_priority(char c) {
if (c == '+' || c == '-') return 0;
else if (c == '*' || c == '/') return 1;
else if (c == '^' || c == '%') return 2;
return -1;
}
// Determine if the precedence of operator1 is less than, equal to, or greater than
// the precedence of operator2. The function returns -1, 0 and 1, respectively.
int precedence(char op1, char op2) {
int op1_p = op_priority(op1);
int op2_p = op_priority(op2);
if (op1_p < op2_p) return -1;
else if (op1_p > op2_p) return 1;
else return 0;
}
// Push a value on the stack.
void push(StackNodePtr *topPtr, char value) {
StackNodePtr temp = (StackNodePtr) emalloc(sizeof (StackNode));
temp->data = value;
temp->nextPtr = *topPtr;
*topPtr = temp;
}
// Pop a value off the stack.
char pop(StackNodePtr *topPtr) {
StackNodePtr t = *topPtr;
if (NULL != *topPtr) {
char c = t->data;
*topPtr = t->nextPtr;
free(t);
return c;
} else {
printf("Stack is empty.\n");
return '\0';
}
}
// Return the top value of the stack without popping the stack.
char peek(StackNodePtr topPtr) {
if (NULL != topPtr) {
return topPtr->data;
} else {
printf("Stack is empty.\n");
}
}
// Determine if the stack is empty.
int isEmpty(StackNodePtr topPtr) {
if (NULL == topPtr) return true;
return false;
}
// Prints the stack
void printStack(StackNodePtr topPtr) {
if (!isEmpty(topPtr)){
StackNodePtr t = topPtr;
while (NULL != t) {
printf("%c\t", t->data);
t = t->nextPtr;
}
printf("NULL\n");
} else {
printf("Stack is empty.\n");
}
}
// Convert the infix expression to postfix notation.
void convertToPostfix(char infix [], char postfix [], int expression_length) {
printf("At top of cnvToPostfix\n");
int infix_count = 0;
int postfix_count = 0;
////////////////////////////////////////////
StackNodePtr *stack;
push(stack, '(');
printStack(*stack);
////////////////////////////////////////////
infix[expression_length] = ')';
while (isEmpty(*stack)) {
char current = infix[infix_count++];
if (isdigit(current)) {
postfix[postfix_count++] = current;
} else if (current == '(') {
push(stack, current);
} else if (isOperator(current)) {
while (true) {
char top = peek(*stack);
if (isOperator(top) && precedence(current, top) >= 0) {
postfix[postfix_count++] = pop(stack);
} else {
break;
}
}
push(stack, current);
}
else if (current == ')') {
while (true) {
char top = peek(*stack);
if (top == '(') {
pop(stack);
break;
} else {
postfix[postfix_count++] = pop(stack);
}
}
}
}
}
int main() {
printf("Testing stack\n");
printf("Pushing 1, 2, and 3 onto stack, peeking and popping.\n");
StackNodePtr *stack;
push(stack, '1');
push(stack, '2');
push(stack, '3');
printf("Printing stack\n\n");
printStack(*stack);
printf("Peek: %c\n", peek(*stack));
printf("Pop: %c\n", pop(stack));
printf("Printing stack\n");
printStack(*stack);
/*
printf("Enter the infix expression.\n");
char c;
char infix [1024];
int count = 0;
while ((scanf("%c", &c)) == 1) {
if ((int) c == 10) break;
infix[count++] = c;
}
printf("The original infix expression is:\n");
print_array(infix, count);
char postfix [count];
convertToPostfix(infix, postfix, count);
printf("The expression in postfix notation is:\n");
print_array(postfix, count);
*/
return 0;
}
I see at least one immediate problem:
StackNodePtr *stack;
push(stack, '1');
Where is the initialisation for your stack? Use of uninitialised pointers is instant "undefined behaviour" territory.
If you look closely at your push code, you'll see it inserts the new item before the current one but set the new item's nextPtr pointer to the previous (uninitialised) value.
That means, the last item in the stack won't actually point to NULL.
You're not really initialising your stacks:
StackNodePtr *stack;
push(stack, '(');
It's also potentially confusing having StackNodePtr being a pointer type, and stack being a pointer to that type. You need to be clear in every possible usage how many levels of indirection should be applied.
To start with, imagine passing the new stack firstly to isEmpty:
StackNodePtr *stack;
printf("%d\n", isEmptypush(*stack));
What's isEmpty going to do on the value it is passed?
I think what you want instead is:
StackNodePtr stack = NULL;
push(&stack, '(');
Other uses of stack in that function should similarly be changed from *stack to stack, or stack to &stack.