Converting an infix to a prefix using stacks in C - c

I am trying to use stacks with linked lists to convert an infix expression to a prefix expression. Here is my code for the same:
#include <stdio.h>
#include <stdlib.h>
#define M 100
struct Stack{
char ele;
struct Stack *next;
};
struct Stack* next_node(char element){
struct Stack *node=(struct Stack *)malloc(sizeof(struct Stack));
node->ele=element;
node->next=NULL;
return node;
}
int isEmpty(struct Stack *node){
return node==NULL;
}
void push(struct Stack **node, char element){
struct Stack *temp=next_node(element);
temp->next=*node;
*node=temp;
}
char pop(struct Stack **node){
if(isEmpty(*node)){
return 0;
}
struct Stack *temp=*node;
*node=(*node)->next;
char revc=temp->ele;
free(temp);
return revc;
}
char* rev(char str[]){
int i, n;
for(n=0;str[n]!='\0';n++);
struct Stack *s=(struct Stack *)malloc(sizeof(struct Stack));
for(i=0;i<n;i++)
push(&s, str[i]);
for(i=0;i<n;i++)
str[i]=pop(&s);
if(str[i]=='(')
str[i]=')';
else if(str[i]==')')
str[i]='(';
return str;
}
int isVariable (char ch){
return (ch>='a' && ch<='z')||(ch>='A'&&ch<='Z');
}
int precedence(char ch){
switch(ch){
case '+':
case '-': return 1;
case '*':
case '/': return 2;
}
return -1;
}
char* postfix(char str[]){
int i, j=0;
struct Stack *s=NULL;
for(i=0;str[i]!='\0';i++){
if(isVariable(str[i]))
str[j++]=str[i];
else if(str[i]==')')
push(&s, str[i]);
else if(str[i]=='('){
while(!isEmpty(s)&&s->ele!=')')
str[j++]=pop(&s);
if(!isEmpty(s)&&s->ele!=')')
return 0;
else
pop(&s);
}
else{
while(!isEmpty(s)&&precedence(str[i])<=precedence(s->ele))
str[j++]=pop(&s);
push(&s, str[i]);
}
}
while(!isEmpty(s))
str[j++]=pop(&s);
str[j++]='\0';
return str;
}
void prefix(char str[]){
str=rev(str);
str=postfix(str);
str=rev(str);
printf("The prefix equivalent is: %s\n", str);
}
int main()
{
char string[M], op[1];
do{
printf("Enter the infix expression: ");
scanf("%s", string);
prefix(string);
printf("Do you want to go again?(Y/N): ");
scanf("%s", op);
}while(op[0]=='Y');
}
While the code works fine for expressions with no parantheses, it fails with expressions that do.
For example: when I input something like "(a+b-c) *d-(e+f)", my output is "- * a-b+cd+ef", when the output should be "- * -+abcd+ef".
Why is it happening? Any help is welcome! :-)

Related

I am trying to code queue using stack. There is no error while I am running the code but the stack is not able to store the values

I have initialised two stacks using a structure with which I am creating a queue. But the stack is not able to store the values which is why enqueue or dequeue operations are not working properly.
Here is the code:
#include<stdio.h>
#include<stdlib.h>
struct stack{
int top;
int size;
int *s;
};
int isfull(struct stack *st){
if(st->top==st->size-1){
return 1;
}
return 0;
}
int isempty(struct stack *st){
if(st->top==-1){
return 1;
}
return 0;
}
void push(struct stack *st,int x){
if(isfull(st)){
printf("FULL!!\n");
}
else{
st->top++;
st->s[st->top]=x;
}
}
int pop(struct stack *st){
int x=-1;
if(isempty(st)){
printf("EMPTY!!\n");
}
else{
x=st->s[st->top];
st->top--;
}
return x;
}
void enqueue(struct stack s1,int x){
push(&s1,x);
}
int dequeue(struct stack s1,struct stack s2){
int x=-1;
if(isempty(&s2)){
if(isempty(&s1)){
printf("QUEUE IS EMPTY!!\n");
return x;
}
else{
while(!isempty(&s1)){
push(&s2,pop(&s1));
}
}
}
return pop(&s2);
}
void display(struct stack st){
int i;
for(i=0;i<=st.top;i++){
printf("%d",st.s[i]);
}
}
int main(){
int n,choice;
struct stack s1,s2;
printf("ENTER SIZE OF QUEUE:");
scanf("%d",&n);
s1.size=n;
s2.size=n;
s1.top=-1;
s2.top=-1;
s1.s=(int *)malloc(s1.size*sizeof(int));
s2.s=(int *)malloc(s2.size*sizeof(int));
while(1){
printf("1.ENQUEUE\n");
printf("2.DEQUEUE\n");
printf("3.DISPLAY\n");
printf("4.EXIT\n");
printf("ENTER YOUR CHOICE:");
scanf("%d",&choice);
switch(choice){
case(1):
int x;
printf("ENTER DATA:");
scanf("%d",&x);
enqueue(s1,x);
break;
case(2):
int m;
m=dequeue(s1,s2);
printf("ELEMENT DELETED IS:%d\n",m);
break;
case(3):
display(s2);
break;
case(4):
exit(0);
}
}
return 0;
}
What is the error? I think there might be an issue with passing the values to the function.
The main issue is that the enqueue and dequeue don't take pointers as arguments, but struct stack. This means the function gets a copy of the given struct, and that the pointer you pass to push and pop (like &s1) is pointing to that local structure, not to the one in main. By consequence any update to the top member of that stack will not be seen by the caller.
I would suggest to:
Consistently pass pointers to struct typed arguments. This was well done for the push and pop functions, and there is no reason why it should not be done the same way for enqueue and dequeue functions.
Define a struct queue so that you abstract a bit that there are two stacks involved and don't have to pass both of them as argument to dequeue.
Create separate functions for:
creating a new stack
displaying a stack
creating a new queue
displaying a queue
checking if a queue is empty
Here is how your code would then look:
#include <stdio.h>
#include <stdlib.h>
struct stack {
int top;
int size;
int *s;
};
struct stack* newstack(int size) {
struct stack *s = malloc(sizeof(struct stack));
s->size = size;
s->s = malloc(size*sizeof(int));
s->top = -1;
return s;
}
int isfull(struct stack *st) {
return st->top == st->size - 1;
}
int isempty(struct stack *st) {
return st->top == -1;
}
void push(struct stack *st, int x) {
if (isfull(st)){
printf("Full!\n");
} else {
st->top++;
st->s[st->top] = x;
}
}
int pop(struct stack *st) {
int x = -1;
if (isempty(st)){
printf("Empty!\n");
} else {
x = st->s[st->top];
st->top--;
}
return x;
}
void displaystack(struct stack *st) {
for(int i = 0; i <= st->top; i++) {
printf("%d ", st->s[i]);
}
}
struct queue {
struct stack *s1;
struct stack *s2;
};
struct queue* newqueue(int size) {
struct queue *q = malloc(sizeof(struct queue));
q->s1 = newstack(size);
q->s2 = newstack(size);
return q;
}
int isemptyqueue(struct queue *q) {
return isempty(q->s1) && isempty(q->s2);
}
void enqueue(struct queue *q, int x) {
push(q->s1, x);
}
int dequeue(struct queue *q) {
int x = -1;
if (isemptyqueue(q)) {
printf("Queue is empty!\n");
return -1;
}
if (isempty(q->s2)) {
while (!isempty(q->s1)) {
push(q->s2, pop(q->s1));
}
}
return pop(q->s2);
}
void displayqueue(struct queue *q) {
displaystack(q->s1);
printf("| ");
displaystack(q->s2);
printf("\n");
}
int main() {
int n, choice, x, m;
printf("Enter the size of the queue: ");
scanf("%d", &n);
struct queue *q = newqueue(n);
while (choice != 4) {
printf("1. Enqueue\n");
printf("2. Dequeue\n");
printf("3. Display\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter data: ");
scanf("%d", &x);
enqueue(q, x);
break;
case 2:
m = dequeue(q);
printf("The deleted element is: %d\n", m);
break;
case 3:
displayqueue(q);
break;
}
}
return 0;
}

Segmentation fault while implementing stack as an array

This is a menu-driven program that carries out basic stack operations using arrays in the C programming language. The functions that are performed are push, pop, peep,isempty and isfull.
#include<stdio.h>
#include<stdlib.h>
struct stack
{
long int top;
long int size;
char* key;
};
int is_empty(struct stack *s) //check if its empty
{
if(s->top==-1)
{
return -1;
}
else
{
return 1;
}
}
int is_full(struct stack *s) //check if its full
{
if (s->top ==s->size-1)
{
return -1;
}
else
{
return 1;
}
}
void push(struct stack *s, char x) //pushes into stack
{
int check;
check = is_full(s);
if(check==-1)
{
printf("-1\n");
}
else
{
s->top = s->top+1;
s->key[s->top]=x;
}
}
void pop(struct stack *s) //deletes the last element
{
int check;
check = is_empty(s);
if(check==-1)
{
printf("-1\n");
}
else
{
char k;
k = s->key[s->top];
printf("%c\n",k);
s->top--;
}
}
void peep(struct stack *s) //prints the last element without deleting
{ int check;
char k;
check = is_empty(s);
if (check == -1)
{
printf("-1\n");
}
else
{
k = s->key[s->top];
printf("%c \n",k);
}
}
int main()
{
char ch;
char x;
long int n;
struct stack *s;
scanf("%ld ", &n);
s->size = n; //initialise the size
s->top = -1; //setting as -1 base case
s->key= (char *)malloc(n*sizeof(char)); //dynamic allocation of keys
while(1)
{
scanf("%c ",&ch);
switch(ch)
{
case 'i':
scanf("%c ",&x);
push(s,x);
break;
case 'd':pop(s);
break;
case 'p':peep(s);
break;
case 't':exit(0); //termination case
}
}
return 0;
}
This is a C program that is working for me in some online compilers but in VScode and other compilers, it's showing a segmentation fault without any output. This is an implementation of stack using arrays. Is it a problem with any of the scanf functions?
You have created a pointer variable s and then access the size field on that struct.
struct stack *s;
scanf("%ld ", &n);
s->size = n; //initialise the size
Except s doesn't actually point to anything at this point. You need to either statically or dynamically allocate memory for that struct.
struct stack s;
Or:
struct stack *s = malloc(sizeof(struct stack));

Unable to pop top element from the linked list

I was trying to make a simple Linked List program, also when I'm trying to pop the first element from the list , it's not popping and it still remains the first element in the list, please help me resolve this error.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void create(stack *s){
if(s == NULL){
s = (stack*)malloc(sizeof(stack)*1);
(s->next)=NULL;
}
else{
stack *temp = (stack*)malloc(sizeof(stack)*1);
(temp->next)=s;
s=temp;
}
}
void push(stack *s, char x){
create(s);
(s->value)=x;
}
void isEmpty(stack *s){
if(s == NULL){
printf("List is Empty!\n");
}
else{
printf("List is not Empty!\n");
}
}
char pop(stack *s){
if(s == NULL){
isEmpty(s);
return -1;
}
char x=s->value;
s=(s->next);
return x;
}
int main(int argc , char* argv[]){
stack *s;
create(s);
char choice,data;
printf("Stack Created\n\n");
do{
printf("Choose Option: pUsh, pOp, pEek, iseMpty, getSize, eXit: \n");
scanf(" %c",&choice);
switch(choice){
case 'U':{
printf("Enter the element to be pushed: \n");
scanf(" %c",&data);
push(s, data);
break;
}
case 'O':{
data=pop(s);
if(data != NULL){
printf("Popped: %c\n", data);
}
break;
}
}
}while(1);
return 0;
}
The line s=s->next; has no effect because s is a local varaible. You need to return the new value of s or use pointers to modify the caller's version.
I changed the argument to pop() and push() from stack * to stack **, so that we can update the stack not a local variable. I removed create() as it is basically what happens during the push and I integrated it with that.
The rest is straightforward and I also added the free() call in pop(). Take a look:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack{
int value;
struct stack *next;
}stack;
void push(stack **s, int x){
stack *temp = (stack*)malloc(sizeof(stack)*1);
temp->value = x;
temp->next = NULL;
if(*s == NULL){
*s = temp;
}else{
temp->next = *s;
*s=temp;
}
}
char pop(stack **s){
if(*s == NULL){
return -1;
}
char x=(*s)->value;
stack *tmp = *s;
*s=(*s)->next;
free(tmp);
return x;
}
int main(int argc , char* argv[]){
stack *s;
char choice,data;
printf("Stack Created\n\n");
do{
printf("Choose Option: pUsh, pOp, pEek, iseMpty, getSize, eXit: \n");
scanf(" %c",&choice);
switch(choice){
case 'U':{
printf("Enter the element to be pushed: \n");
scanf(" %c",&data);
push(&s, data);
break;
}
case 'O':{
data=pop(&s);
if(data != -1){
printf("Popped: %c\n", data);
} else {
printf("Stack is empty. nothing popped");
}
break;
}
}
}while(1);
return 0;
}
Here you have to use pointer to pointer if u want to pass pointer as an argument
char pop(stack **s)
{
**s=s->next;
}
this is a temporary solution u should also consider deleting the memory you allocated using the malloc function or else it will lead to memory leak
also pass the address of the pointer s while you call it in the pop function

Program immediately terminates with segfault when using scanf

When I use gets() or fgets() instead of scanf(), the program does execute completely but prints segmentation fault(core dumped) in the end! I don't understand why am I getting segfault in both the cases. Here is the code for converting an infix to postfix exp using stacks.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stack{
int top;
int capacity;
int *array;
}stack;
stack* createstack(char *);
void push(stack* ,int );
int isempty(stack *);
int pop(stack *st);
int peek(stack *st);
int precedence(char c);
int main(){
char exp[100];
char post[100];
int k=-1;
stack *st;
int i=0,p=0;
printf("enter string expression: ");
//gets(exp);
//fgets(exp, sizeof(exp), stdin);
scanf("%s",exp);
printf("Infix expression : %s",exp);
st=createstack(exp);
for(i=0;i<strlen(exp);i++){
if( (exp[i]>='a' && exp[i]<='z') || (exp[i]>='A' && exp[i]<='Z'))
post[++k]=exp[i];
else if(exp[i]=='(')
push(st,exp[i]);
else if(exp[i]==')'){
while(!isempty(st) && peek(st)!='(')
post[++k]=pop(st);
pop(st);
}
else{
while(precedence(exp[i]) < precedence(peek(st)))
post[++k]=pop(st);
push(st,exp[i]);
}
}
while(!isempty(st))
post[++k]=pop(st);
//post[++k]='\0';
printf("Postfix expression :\n%s\n",post);
return 0;
}
stack* createstack(char *exp){
stack* st;
st->top=-1;
st->capacity=strlen(exp);
st->array=(int*)malloc(st->capacity * sizeof(int));
printf("Stack created successfully\n");
return st;
}
void push(stack* st,int val){
st->array[++st->top]=val;
}
int isempty(stack *st){
return st->top==-1;
}
int pop(stack *st){
return st->array[st->top--];
}
int peek(stack *st){
return st->array[st->top];
}
int precedence(char c){
switch(c){
case '(':
return 0;
break;
case '+':
return 1;
break;
case '-':
return 1;
break;
case '*':
return 2;
break;
case '/':
return 2;
break;
case '^':
return 3;
break;
}
}
In your code,
stack* st;
st->top=-1;
you're using st uninitialized which in turn invokes undefined behaviour.
You need to allocate memory to st before using it.
Try something like
stack* st = malloc(sizeof*st); //also, check for malloc success
That said,
Please see why not to cast the return value of malloc() and family in C.
The recommended signature of main() is int main(void).

Segmentation fault on scanf in C. Doesn't make sense [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have done this countless times before and for some reason now I cannot seem to scanf a string in C.
Here is my code for the specific function:
int putIn(NODE **head,NODE **current,NODE **prev) {
char tempName[40];
printf("Enter party name: ");
scanf("%s",tempName);
printf("Good?");
current=head;
int match=0;
printf("Hi");
while (*current !=NULL) {
printf("No");
if (strcmp((*current)->name,tempName)==0) {
printf("Name exists already");
match=1;
*current=(*current)->next;
}
}
printf("HI");
The function does not even get to the printf("Good"); statement. thanks for your help!
Edit:
Here is all code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define NODE struct node
struct node {
char name[20];
int number;
NODE *next;
};
int counter;
int putIn(NODE **head,NODE **current,NODE **prev);
int delete(NODE **head,NODE **current,NODE **prev);
int show(NODE **head,NODE **current,NODE **prev);
NODE *head=NULL;
NODE *current=NULL;
NODE *prev=NULL;
char tempName[40];
int main() {
int whileLoop=0;
while(whileLoop==0) {
printf("Enter A Command: (1)Insert Party (2)Delete Party (3)Show List (4)Quit: ");
int selection;
scanf("%d",&selection);
switch(selection) {
case 1:
putIn(&head,&current,&prev);
break;
case 2:
delete(&head,&current,&prev);
break;
case 3:
show(&head,&current,&prev);
break;
case 4:
whileLoop=1;
break;
default:
putIn(&head,&current,&prev);
}
}
return 0;
}
int putIn(NODE **head,NODE **current,NODE **prev) {
//char tempName[40];
printf("Enter party name: ");
scanf("%s",tempName);
printf("Good?");
current=head;
int match=0;
printf("Hi");
while (*current !=NULL) {
printf("No");
if (strcmp((*current)->name,tempName)==0) {
printf("Name exists already");
match=1;
*current=(*current)->next;
}
}
printf("HI");
current=(NODE **)malloc(sizeof(NODE *));
if (*head==NULL) {
head=current;
}
(*current)->next=NULL;
strcpy((*current)->name,tempName);
printf("enter party size: ");
scanf("%d",&(*current)->number);
prev=head;
int i;
for (i=0;i<counter-1;i++){
*prev=(*prev)->next;
}
if (counter!=0) {
(*prev)->next=*current;
}
printf("%d",(*head)->number);
counter+=1;
return 0;
}
int delete(NODE **head,NODE **current,NODE **prev) {
int openTable;
printf("Enter open table size: ");
scanf("%d",&openTable);
current=head;
int match=0;
int grow=0;
while (*current!=NULL) {
if ((*current)->number<=openTable) {
match=1;
printf("A table of %d has been removed",(*current)->number);
prev=head;
int i;
for (i=0;i<grow-1;i++) {
*prev=(*prev)->next;
}
(*prev)->next=(*current)->next;
free(*current);
counter-=1;
} else {
grow+=1;
*current=(*current)->next;
}
}
return 0;
}
int show(NODE **head,NODE **current,NODE **prev) {
if (head==NULL) {
printf("\nNo data entered");
}
else {
printf("\nHere is the waiting list: \n");
}
current=head;
while (*current !=NULL) {
printf("Name: %s Size: %d\n",(*current)->name,(*current)->number);
*current=(*current)->next;
}
return 0;
}
The problem has nothing to do with scanf if you don't enter something too long. Your candidates for crash are:
while (*current != NULL) {
and
if (strcmp((*current)->name, tempName) == 0) {
depending on the initialization status of your pointers to pointers, one of these might lead to segfault.
You have to provide the context of the function call where you call putIn(...);
Edit: After you gave insight into your logic, here's the error:
You start out with:
NODE *head = NULL;
NODE *current = NULL;
NODE *prev = NULL;
and, without any further initialization, go into:
putIn(&head, &current, &prev);
where you do the following:
...
current = (NODE **)malloc(sizeof(NODE *));
...
which means, the actual parameter (an important address value, that has been copied on the stack) in the function call is overwritten by the malloc result (which can't be correct, maybe you meant *current = (NODE *) malloc(sizeof(NODE)); ... or sth. else).
In the next step, you initialize (disconnect too) head with the already-disconnected current:
if (*head == NULL) {
head = current;
}
In the next line, you dereference the allocated pointer and access it as it would point to a structure node (with a NODE* member), which has not been allocated so far ...
(*current)->next = NULL;
which segfaults (because *current does not point to an allocated structure node).

Resources