I am learning data structures and C and make a Postfix calculator as an exercise. the calculator works fine. but it is not able to get the equation from the user, For now, I defined a expression in the code itself.
What i want is, the user can enter expression one by one so it will give the value until he enters "Stop". How can i do that ??
This is my code
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// Stack type
struct Stack
{
int top;
unsigned capacity;
int* array;
};
// Stack Operations
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));
if (!stack->array) return NULL;
return stack;
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1 ;
}
int peek(struct Stack* stack)
{
return stack->array[stack->top];
}
int pop(struct Stack* stack)
{
if (!isEmpty(stack))
return stack->array[stack->top--] ;
return '$';
}
void push(struct Stack* stack,int op)
{
stack->array[++stack->top] = op;
}
int evaluatePostfix(char* exp)
{
struct Stack* stack = createStack(strlen(exp));
int i;
if (!stack) return -1;
for (i = 0; exp[i]; ++i)
{
if(exp[i]==' ')continue;
else if (isdigit(exp[i]))
{
int num=0;
while(isdigit(exp[i]))
{
num=num*10 + (int)(exp[i]-'0');
i++;
}
i--;
push(stack,num);
}
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[] = "100 200 + 2 / 5 * 7 +";
printf ("%d", evaluatePostfix(exp));
return 0;
}
I want to change this a a user input expression
char exp[] = "100 200 + 2 / 5 * 7 +";
How can i do it. any leads ???
Related
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));
So i am writing a postfix program in C using linked list and my output values are off, for example the expression:[ 3 4 5 * + 6 7 * 8 + 9 * + ] should equal 473, but my program returns 4.
I also need to check for errors such as (2 3 - where there's no closing ). right now it ignores it and gives me a value.
My code is as below:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// Node to store data and address of next next
struct Node
{
int value;
struct Node *next;
} ;
// Stack type
typedef struct Stack
{
int value;
struct Node* top;
struct Node* back;
} Stack;
// Stack Operations
struct Stack* createStack()
{
Stack* stack = (Stack*) malloc(sizeof(Stack));
if (!stack)
return NULL;
stack->top = NULL;
stack->value = 0;
return stack;
}
// check stack is empty or not
int isEmpty(Stack* stack)
{
return stack->top == NULL;
}
// return peek of stack
int peek(Stack* stack)
{
return stack->top->value;
}
/**
* return top of stack and pop element from top of stack
*/
int pop(Stack* stack)
{
char top;
if (!isEmpty(stack)) // no empty
{
top = stack->top->value;
stack->top = stack->top->next;
stack->value--;
return top;
}
return -1;
}
/*
* push an element into stack
*/
void push(Stack* stack, char op)
{
struct Node *newNode = (struct Node*) malloc(sizeof(struct Node*));
newNode->next = NULL;
newNode->value = op;
if (isEmpty(stack))
{
stack->top = newNode;
stack->value++;
return;
}
newNode->next = stack->top;
stack->top = newNode;
}
// The main function that returns value of a given postfix expression
int evaluatePostfix(char* exp)
{
// Create a stack of capacity equal to expression size
Stack* stack = createStack();
int i, val, val2, res;
// Scan all characters one by one
for (i = 0; i < strlen(exp); i++)
{
// If the scanned character is an operand (number here),
// push it to the stack.
if (isdigit(exp[i]))
push(stack, exp[i] - '0');
// If the scanned character is an operator, pop two
// elements from stack apply the operator
else
{
val = pop(stack);
val2 = pop(stack);
switch (exp[i])
{
case '+':
res = val2 + val;
push(stack, res);
break;
case '-':
res = val2 - val;
push(stack, res);
break;
case '*':
res = val2 * val;
push(stack, res);
break;
case '/':
res = val2 / val;
push(stack, res);
break;
}
push (stack, res);
}
}
return pop(stack);
}
// Driver program to test above functions
int main()
{
char exp [20];
Stack* stack = createStack();
printf("Enter postfix expression: ");
scanf("%s", exp);
printf ("postfix result: %d\n", evaluatePostfix(exp));
return 0;
}
For starters this structure definition
// Stack type
typedef struct Stack
{
int value;
struct Node* top;
struct Node* back;
} Stack;
does not make a great sense. For example the data member back is not used. The meaning of the data member value is unknown.
There is no sense to define an object of the type Stack dynamically. So this function
struct Stack* createStack()
{
Stack* stack = (Stack*) malloc(sizeof(Stack));
if (!stack)
return NULL;
stack->top = NULL;
stack->value = 0;
return stack;
}
is redundant.
The function pop uses an object of the type char instead of the type int to return a value stored in the stack. An object of the type char is unable to store the positive value equal to for example 473.
/**
* return top of stack and pop element from top of stack
*/
int pop(Stack* stack)
{
char top;
^^^^^^^^^^
if (!isEmpty(stack)) // no empty
{
top = stack->top->value;
stack->top = stack->top->next;
stack->value--;
return top;
}
return -1;
}
Also it does not free the popped node. So the function produces memory leaks.
The same problem tales place in the function push declared like
void push(Stack* stack, char op);
^^^^^^^^^
Also you forgot to increase the data member value when the stack is not empty.
if (isEmpty(stack))
{
stack->top = newNode;
stack->value++;
return;
}
newNode->next = stack->top;
stack->top = newNode;
// stack->value++; <===
The function evaluatePostfix should have the qualifier const with its parameter
int evaluatePostfix( const char* exp)
because the passed string is not changed in the function.
It is inefficient to use the function strlen in the for loop
for (i = 0; i < strlen(exp); i++)
Within the function you push a result of calculation twice under each case label and after the switch statement
switch (exp[i])
{
case '+':
res = val2 + val;
push(stack, res);
break;
case '-':
res = val2 - val;
push(stack, res);
break;
case '*':
res = val2 * val;
push(stack, res);
break;
case '/':
res = val2 / val;
push(stack, res);
break;
}
push (stack, res);
It is desirable to skip embedded white spaces in the string.
And as the stack was allocated dynamically you need to free it before exiting the function.
Here is a demonstrative program that shows how the program can be written.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct Stack
{
struct Node
{
int value;
struct Node *next;
} *top;
} Stack;
int push( Stack* stack, int value )
{
struct Node *newNode = malloc( sizeof( struct Node ) );
int success = newNode != NULL;
if ( success )
{
newNode->value = value;
newNode->next = stack->top;
stack->top = newNode;
}
return success;
}
void pop( Stack *stack )
{
if ( stack->top != NULL )
{
struct Node *tmp = stack->top;
stack->top = stack->top->next;
free( tmp );
}
}
int isEmpty( Stack *stack )
{
return stack->top == NULL;
}
int peek( Stack *stack )
{
return stack->top->value;
}
// The main function that returns value of a given postfix expression
int evaluatePostfix( const char *exp )
{
// Create a stack of capacity equal to expression size
Stack stack = { NULL };
int res = 0;
// Scan all characters one by one
for ( ; *exp; ++exp )
{
if ( !isspace( ( unsigned char )*exp ) )
{
// If the scanned character is an operand (number here),
// push it to the stack.
if ( isdigit( ( unsigned char ) *exp ) )
{
push( &stack, *exp - '0' );
}
// If the scanned character is an operator, pop two
// elements from stack apply the operator
else
{
int val = peek( &stack );
pop( &stack );
int val2 = peek( &stack );
pop( &stack );
res = 0;
switch ( *exp )
{
case '+':
res = val2 + val;
break;
case '-':
res = val2 - val;
break;
case '*':
res = val2 * val;
break;
case '/':
res = val2 / val;
break;
}
push( &stack, res );
}
}
}
if ( !isEmpty( &stack ) )
{
res = peek( &stack );
pop( &stack );
}
return res;
}
int main(void)
{
const char *exp = "3 4 5 * + 6 7 * 8 + 9 * +";
printf( "postfix result: %d\n", evaluatePostfix( exp ) );
return 0;
}
The program output is
postfix result: 473
You could append the program with a code that will check whether a current symbol of the passed string is a valid symbol. That is whether the passed expression is correct.
This is a c program to reverse the order of words in a sentence(using stacks) read as input, but all I can get is the reverse of the each word in the sentence. How can I reverse the sentence(separated with ' ' or ',')?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// A structure to represent a stack
struct Stack
{
int top;
unsigned capacity;
char* array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (char*) malloc(stack->capacity * sizeof(char));
return stack;
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// Function to add an item to stack. It increases top by 1
void push(struct Stack* stack, char item)
{
if (isFull(stack))
return;
stack->array[++stack->top] = item;
}
char pop(struct Stack* stack)
{
if (isEmpty(stack))
return 0;
return stack->array[stack->top--];
}
// A stack based function to reverese a string
void reverse(char str[])
{
int n = strlen(str);
struct Stack* stack = createStack(n);
// Push all characters of string to stack
int i;
for (i = 0; i < n; i++)
push(stack, str[i]);
for (i = 0; i < n; i++)
str[i] = pop(stack);
}
int main()
{
char str[50];
fgets(str, sizeof(str), stdin);
str[strlen(str)-1]='\0';
reverse(str);
printf("Reversed string is %s", str);
return 0;
}
Try this code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// A structure to represent a stack
struct Stack
{
int top;
unsigned capacity;
//char* array;
char** array;
};
struct Stack* createStack(unsigned capacity)
{
if( capacity < 1 )
{
capacity = 1;
}
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (char**) malloc(stack->capacity * sizeof(char*));
return stack;
}
void resizeStack( struct Stack* stack , int new_size )
{
if( NULL != stack && new_size > stack->capacity ) // Only support expansion
{
char ** old_array = stack->array ;
stack->array = (char**) malloc(new_size * sizeof(char*));
memcpy(stack->array,old_array,stack->capacity * sizeof(char*));
free(old_array);
stack->capacity = new_size ;
}
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// Function to add an item to stack. It increases top by 1
void push(struct Stack* stack, char *item)
{
if ( isFull(stack) )
{
resizeStack(stack, stack->capacity * 2 );
}
stack->array[++stack->top] =(char *) malloc(sizeof(char)*(strlen(item) +1));
strcpy(stack->array[stack->top] , item);
}
char * pop(struct Stack* stack)
{
char * ret = NULL;
if(! isEmpty(stack) )
{
ret = stack->array[stack->top];
stack->array[stack->top] = NULL ;
stack->top --;
}
return ret;
}
void freeStack(struct Stack* stack)
{
if( NULL != stack && NULL != stack->array )
{
while( ! isEmpty(stack) )
{
free(pop(stack));
}
free(stack->array);
}
else
{
printf(" freeStack try to free NULL ");
}
}
#define SEPARATER ' '
// A stack based function to reverese a string
void reverse(char str[])
{
int n = strlen(str);
struct Stack* stack = createStack(4);
char sep[2];
sep[0] = SEPARATER;
sep[1] = 0 ;
char * pch = strtok(str,sep);
while( NULL != pch )
{
push(stack,pch);
pch = strtok(NULL,sep);
}
char * swap_buff = (char*)malloc((n+1) * sizeof(char));
char * cp_buff = swap_buff;
do
{
char * top = pop(stack);
strcpy(cp_buff , top);
cp_buff += strlen(top);
*cp_buff++ = SEPARATER;
}while( ! isEmpty(stack) );
swap_buff[n] = 0;
strcpy(str,swap_buff);
freeStack(stack);
}
int main()
{
char str[50];
fgets(str, sizeof(str), stdin);
str[strlen(str)-1]='\0';
reverse(str);
printf("Reversed string is %s\n", str);
return 0;
}
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).
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.