This is a simple program to implement stack using structure pointers. However on running the code my program exits without showing any error.
#include<stdio.h>
#include<stdlib.h>
#define maxsize 5
struct s
{
char array[maxsize];
int top;
};
typedef struct s stack;
int insert(stack *p)
{
char ch;
/*if(p->top==NULL)
{
p->top=-1;
}*/
if(p->top>=maxsize-1)
{
printf("Stack overflows on insertion\n");
}
else
{
printf("Enter the character to be inserted : ");
scanf("\n%c",&ch);
p->top++;
p->array[p->top]=ch;
}
}
int delete(stack *p)
{
if(p->top==-1)
{
printf("Stack underflows on deletion\n");
}
else
{
p->top--;
}
}
int display(stack *p)
{
int i;
if(p->top==-1)
{
printf("Stack is empty\n");
}
else
{
for(i=0;i<=p->top;i++)
{
printf("%c",p->array[i]);
}
printf("\n");
}
}
int main()
{
int c;
stack *p;
p->top=-1;
while(1)
{
printf("1--> INSERT 2--> DELETE 3--> DISPLAY\n");
scanf("%d",&c);
switch(c)
{
case 1:
insert(p);
break;
case 2:
delete(p);
break;
case 3:
display(p);
break;
default:
printf("ERROR : Invalid Choice");
}
}
}
This program contains three functions to push, pop and display the elements in the stack, and the last main function is from where the function call is executed.
The program gets compiled successfully with 0 errors, but while running it exits without displaying anything.
When you declare:
stack *p;
It is just declaring a pointer. You need to allocate memory if you want to use the pointer - as you do here (this will segfault):
p->top=-1;
Update the first line to the following:
stack *p = malloc(sizeof(stack));
malloc() will allocate the requested memory for use - anything dynamically allocated should also be free()'d
Related
I have tried creating a program that uses simple stack functions like push to add the contents of the statement onto a stack from where I then print out each character and then reverse the statement. I have used the '.' and '->' member access variables to change the contents of the struct based stack. Upon compiling it prints out the original statement, but after that it gives a segmentation error, saying I am attempting to dereference an uninitialised pointer. Can someone guide me as to how I should solve this problem as it isn't stating the line I have made the problem either.
#include <stdio.h>
#define MAX 1000
#define FULL (MAX - 1)
#define EMPTY -1
typedef struct stack {char s[MAX]; int top;} stack;
int top = EMPTY;
int isFull()
{
if(top == FULL)
return 1;
else
return 0;
}
int isEmpty()
{
if(top == EMPTY)
return 1;
else
return 0;
}
void reset(stack *stk)
{
stk -> top = EMPTY;
}
void push(char c, stack *stk)
{
stk -> top++;
(*stk).s[(*stk).top] = c;
}
char pop(stack *stk)
{
return (*stk).s[(*stk).top--];
}
void print(stack *stk)
{
int i;
while(1)
{
if(isEmpty())
{
printf("Stack underflow\n");
break;
}
for(i = 0; i <= top; i++)
{
printf("%c\n", (*stk).s[i]);
}
printf("\n");
return;
}
}
void reverse(stack *stk)
{
int i;
while(1)
{
if(isEmpty())
{
printf("Stack underflow\n");
break;
}
for(i = top; i >= 0; i--)
{
printf("%c", (*stk).s[i]);
}
printf("\n");
return;
}
}
char peek(const stack *stk)
{
while(1)
{
if(isEmpty())
{
printf("Stack underflow\n");
break;
}
return (*stk).s[(*stk).top];
}
}
int main()
{
stack stack_of_char;
char *str = "i am otto am i";
int i;
reset(&stack_of_char);
printf("original is: %s\n", str);
while(str[i] != '\0')
{
push(str[i++], &stack_of_char);
}
print(&stack_of_char);
reverse(&stack_of_char);
return 0;
}
There are several issues with your program. Let's begin with the global variable top. This is causing problems because on the one hand you have a stack struct responsible for maintaining a stack, and that has its own top. But then you have this global which you're not even using anywhere. It's almost like you added it to get around compiler errors that you didn't understand ;)
So let's ditch that, and fix your stack functions. I'm rearranging the parameters of the push function so that the stack is the first argument. This is a bit more conventional.
typedef struct stack {
char s[MAX];
int top;
} stack;
int isFull(stack *stk)
{
return stk->top == FULL;
}
int isEmpty(stack *stk)
{
return stk->top == EMPTY;
}
void reset(stack *stk)
{
stk->top = EMPTY;
}
void push(stack *stk, char c)
{
if (isFull(stk))
return;
stk->s[++stk->top] = c;
}
char pop(stack *stk)
{
if (isEmpty(stk))
return '\0';
return stk->s[stk->top--];
}
For the pop function, I arbitrarily return a NUL character if the stack is empty, because something must be returned. But really, you should never call this function if the stack is empty.
Let's look at your display functions now. The first thing I notice is that these are really convoluted. There is no need for that complexity. Look here:
void print(stack *stk)
{
for(int i = 0; i <= stk->top; i++)
{
printf("%c\n", stk->s[i]);
}
printf("\n");
}
void reverse(stack *stk)
{
for(int i = stk->top; i >= 0; i--)
{
printf("%c", (*stk).s[i]);
}
printf("\n");
}
char peek(const stack *stk)
{
if (isEmpty(stk))
{
printf("Stack empty!\n");
return '\0';
}
return stk->s[stk->top];
}
And so all that remains is a little tidy-up of your main function, and adjust the parameter order for push.
int main()
{
const char *str = "i am otto am i";
printf("original is: %s\n", str);
stack stack_of_char;
reset(&stack_of_char);
for (int i = 0; str[i]; i++)
{
push(&stack_of_char, str[i]);
}
print(&stack_of_char);
reverse(&stack_of_char);
}
Note also that you shouldn't really be walking over your stack with those functions. The typical way you would use a stack to reverse something is to push values onto it and then pop them off. So, you can print the string in reverse like this:
// Pop characters from stack to print in reverse
while (!isEmpty(&stack_of_char))
{
char c = pop(&stack_of_char);
putc(c, stdout);
}
putc('\n', stdout);
Without initialization, the integer will be a random value. It is the root cause of the memory access error.
You will need to initialize the variable properly. In main function, instead of
int i;,
you should use
int i = 0;.
Assume that you plan to access the value starting from index 0.
I am learning stacks right now and I decided to try to make a little program involving the stack from Magic the Gathering rules, which also follows a LIFO order.
The user asked whether they would like to
play a spell (push)
resolve a spell (pop) or
exit.
Now the tricky part is that I am trying to allow the elements of the stack to be multiple words each. This has been causing A LOT of problems.
I can input a word and print it outside the while(1) loop but if I put it inside everything goes haywire. Any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
typedef struct {
char item[SIZE];
int top;
} stack;
void init(stack*);
void push(stack*, char[]);
char pop(stack*);
void init(stack* st) {
st->top = -1;
}
void push(stack* st, char* value) {
if (st->top == SIZE - 1) {
printf("STACK OVERFLOW\n");
return;
}
st->top++;
strcpy(st->item[st->top], value);
}
char pop(stack* st) {
if (st->top == -1) {
printf("STACK UNDERFLOW\n");
return -1;
}
char value;
strcpy(value, st->item[st->top]);
st->top--;
return value;
}
int main() {
stack st1, st2;
int choice;
char val[20];
init(&st1);
init(&st2);
printf("You have priority. What would you like to do?\n\n");
printf("1. Cast a spell\n2. Resolve the next spell\n3. Pass priority\n\n");
while (1) {
scanf("%d", &choice);
switch (choice) {
case 1:
printf("What is the spell?\n\n");
scanf("%[^\n]s", val);
printf("%s", val);
push(&st1, val);
case 2:
strcpy(val, pop(&st1));
printf("%s resolves.\n\n", val);
case 3:
exit(0);
}
}
return 0;
}
The reason you would be getting errors is that because of the type conversions.
char pop(stack* st) {
if (st->top == -1) {
printf("STACK UNDERFLOW\n");
return -1;
}
char value;
strcpy(value, st->item[st->top]);
st->top--;
return value;
}
The first thing, you don't need to pass the address when dealing with the arrays. The another thing is that you are trying to copy a whole string into a single character variable. So, there are so much type conversion problems in your code.
I suggest you to make the functions of void data type and provide the functionality within the block of the function. Just call the pop function with top value as an argument, and print the string within the function that you are popping.
Stack is a zero order data structure so it doesn't require inputs for popping purpose.
Today I have tried to write a code which convert infix expression to postfix expression, my code is running but not working properly,
I upload my whole code please let me know what is wrong with my code,
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXSTACK 50
typedef char StackEntyType;
typedef enum{false, true}Boolean;
typedef struct{
int top;
StackEntyType entry[MAXSTACK];
}stack;
Creating a stack,
void CreateStack(stack *S){
S->top = -1;
}
Checking is stack empty,
Boolean IsStackEmpty(stack *S){
return S->top==-1;
}
Checking is stack full,
Boolean IsStackFull(stack *S){
return S->top == MAXSTACK-1;
}
Code to push stack element,
void Push(StackEntyType item, stack *S){
if(IsStackFull(&S)){
printf("Stack is overflow\n");
}else{
S->entry[++S->top] = item;
}
}
Code to Pop stack elements,
void Pop(StackEntyType *item, stack *S){
if(IsStackEmpty(&S)){
printf("Stack is underflow\n");
}else{
*item = S->entry[S->top--];
}
}
code to return the top stack element,
char Peek(stack *S){
return S->entry[S->top];
}
code to return operator precedence,
int Oprecedence(char elem){
switch(elem){
case '-':
case '+':
return 0;
case '*':
case '/':
return 1;
case '^':
return 2;
}
}
Main code,
void main()
{
char infix[50];
char postfix[50];
char c;
char elem;
stack S;
int i=0;
int k=0;
CreateStack(&S);
printf("Enter infix expression : ");
scanf("%s", infix);
while(!IsStackFull(&S)){
c = infix[i];
for(i=0; infix[i]='\0'; i++){
if(c=='('){
Push(infix[i], &S);
}else if(isalnum(c)){
postfix[k++] = c;
}else if(c==')'){
while(Peek(&S)!='('){
Pop(&postfix[k++], &S);
Pop(&elem, &S);
}
}else{
while(Oprecedence(Peek(&S))>=Oprecedence(c)){
Pop(postfix[k++], &S);
Push(&c, &S);
}
}
}
}
while(!IsStackEmpty(&S)){
Pop(&postfix[k++], &S);
}
postfix[k] = '\0';
printf("\nPostfix Expression = %s\n", postfix);
}
And also I upload the question below check it,
I'm trying to make a program that creates and reads a binary file, which contains "struct elements"; can you please tell me what I did wrong?
I got errors telling me that "s" is not a pointer in function fread()... so I declared ELEM *s; instead of ELEM s;
#include <stdio.h>
#include <stdlib.h>
typedef struct element{
char name[80];
int p;
}ELEM;
void create()
{
FILE *f;
int d=0;
char c;
ELEM *s;
f=fopen("file.bin","wb");
do{
printf("Add elements to file?: (y/n)");
fflush(stdin);
scanf("%c",&c);
if (c=='y')
{
printf("Name=");
gets((*s).name);
printf("P=");
scanf("%d",(*s).p);
fwrite(s,sizeof(ELEM),1,f);
}
} while(d==0);
fclose(f);
}
void show()
{
FILE *f;
ELEM *s;
f=fopen("file.bin","rb");
while(feof(f)!=NULL)
{
fread(s,sizeof(ELEM),1,f);
puts((*s).name);
printf("\t%d\n",(*s).p);
}
fclose(f);
}
void add()
{
FILE *f;
int d=0;
char c;
ELEM *s;
f=fopen("file.bin","ab");
do{
printf("Add elements to file?: (y/n)");
fflush(stdin);
scanf("%c",&c);
if (c=='y')
{
printf("Name=");
gets((*s).name);
printf("P=");
scanf("%d",(*s).p);
fwrite(s,sizeof(ELEM),1,f);
}
} while(d==0);
fclose(f);
}
/*void function()
{
}*/
int main()
{
int k=0,r;
do{
printf("1 - create file\n2 - add elements to fil\n3 - show elements\n4 - put unique elements in another file\n5 - exit program\n");
scanf("%d",&r);
switch(r)
{
case 1 : create(); break;
case 2 : add(); break;
case 3 : show(); break;
case 4 : printf("Function not defined!\n"); break;
case 5 : k=1; break;
default : printf("Command unrecognized!\n");
}
} while(k==0);
return 0;
}
You declared a pointer but assigned no memory to it. You should revert to a normal variable:
ELEM s;
/* ... */
fwrite(&s,sizeof(ELEM),1,f);
^
Alternatively, in your current code you should do this:
ELEM *s = calloc(1, sizeof *s);
The first parameter passed to fwrite should be an address, and the variable whose address you pass must have enough memory to hold the number of objects you plan to read.
So there are two ways:
Creating Variable on Stack:
You allocate the variable on stack and pass its address to fwrite
ELEM s;
fwrite(&s,sizeof(ELEM),1,f);
or
Dynamic Memory allocation:
ELEM *s;
Should be allocated an memory equivalent to hold no of objects of type ELEM that you want to read.
ELEM *s = malloc(sizeof *s);
In this case remember to free the memory once done with your use:
free(s);
You are not allocating the pointer s in your create function. You probably want something like
s = malloc(sizeof(*s));
memset (s, 0, sizeof(*s));
etc.
And you really should learn to compiler with gcc -Wall -g and to use the gdb debugger.
Also, take time to read a good book about programming in C.
Well, your problems is in the scanf. scanf should get a pointer, so change (*s).p to &(*s).p (or even &s->p)
You should have allocated the pointer to struct ELEM
Assuming this is C:
ELEM *s = malloc(sizeof(ELEM));
If it is C++ just add a cast in front
ELEM *s = (ELEM*) malloc(sizeof(ELEM));
This is program to count individual word count in a variable para as an input.
I tried this by using linked list.
Here variable complete is an array that acts like a hash code and stores all alphabets and I am linking new word as per the hash and if there is same word then I am increasing the count. This is the logic I followed.
But the thing is in the program it is not going into a particular part of the code which is written to take repeated words and it is not increasing the count.
This is my code can any one help me with this.
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define NULL 0
struct wordcount
{
char *s;
int count;
struct wordcount *next;
};
struct checkletter
{
char alph;
struct wordcount *next;
};
struct wordcount * create(char *);
main()
{
char *c,*s1,*intm;
char hastlet;
int hash[26],len,i,k=0,r,j,m=0,t,flag=0;
struct checkletter complete[26];
struct wordcount *node;
clrscr();
for(r=0;r<=25;r++)
{ complete[r].alph=r+97;
complete[r].next=NULL;
}
for(r=0;r<=25;r++)
{
printf("%c",complete[r].alph);
}
printf("\n");
printf("Enter the para :");
gets(c);
len=strlen(c);
//arranging the words and putting them with count
for(i=0;i<len;i++)
{ k=0;
intm='\0';
if(c[i]==' ')
{ for(j=m;j<i;j++)
{
intm[k]=c[j];
k++;
}
intm[k]='\0';
strcpy(s1,intm);
m=k;
m++;
hastlet=s1[0];
for(t=0;t<26;t++)
{
if(complete[t].alph==hastlet)
{
node=complete[t].next;
if(node==NULL)
{
complete[t].next=create(s1);
node=complete[t].next;
break;
}
else
{ while(!strcmp(node->s,s1))
{
node=node->next;
if(node->next==NULL)
{ flag++;
break;
}
}
if(!strcmp(node->s,s1))
(node->count)+=1;
if(flag)
{ node->next=create(s1);
}
} break;
}
}
}
}
//displaying the word that are counted
for(i=0;i<26;i++)
{ node=complete[i].next;
if(complete[i].next!=NULL)
while(1)
{ printf("%s---%d",node->s,node->count);
if(node->next==NULL)
break;
}
}
getch();
}
struct wordcount * create(char *y)
{
struct wordcount *newnode;
newnode->s=y;
newnode->count=0;
newnode->next=NULL;
return newnode;
}
The following is incorrect:
char *c;
...
gets(c);
Using an un-initialized pointer c in gets function leads to a undefined behavior. You need to allocate memory for c which is one greater than the max number of characters you wish to store.
Same is the case with intm.
Also, use fgets in place of gets