Stack-based palindrome checker - c++

i have a problem with my program. It should be program that recognize palindome through the stack. Everything works great, only thing that don't work is printing stacks(original and reversed) after the funcion is done.
Here is my entire code, and the problem is at case d and e:
#include <iostream>
using namespace std;
const int MAXSTACK = 21;
class stack {
private:
int stop;
char stk[MAXSTACK];
public:
stack();
~stack();
stack(const stack& s);
void push(const char c);
char pop();
char top(void);
int emptystack(void);
int fullstack(void);
void stack_print(void);
int stack::create(void);
};
stack::stack()
{
stop = 0;
}
stack::~stack() { }
stack::stack(const stack& s)
{
stop = s.stop;
strcpy(stk,s.stk);
}
void stack::push(const char c)
{
stk[stop++] = c;
}
char stack::pop()
{
return stop--;
}
char stack::top(void)
{
return stk[stop - 1];
}
int stack::emptystack(void)
{
return !stop;
}
int stack::fullstack(void)
{
return stop == MAXSTACK;
}
void stack::stack_print(void)
{
for (int i=0; i<stop; i++)
cout<<stk[i];
cout<<endl;
}
int stack::create(void)
{
return !stop;
}
char menu()
{
char volba;
cout<<"\n";
cout<<" **********.\n";
cout<<"\n";
cout<<" a ... make new containers\n";
cout<<" b ... delete content\n";
cout<<" c ... enter string\n";
cout<<" d ... print on screen first stack\n";
cout<<" e ... print on screen first stack\n";
cout<<" f ... is it palindrom\n";
cout<<" x ... exit\n";
cout<<"\n your choice : ";
cin >> volba;
return volba;
}
int main() {
char palindrome[MAXSTACK];
char volba;
stack original,reversed;
int stackitems = 0,i;
//cin.getline(palindrome,MAXSTACK);
do{
volba = menu();
switch (volba)
{
case'a':
{
original.create();
reversed.create();
cout<<"done'";
break;
}
case'b':
{
original.emptystack();
reversed.emptystack();
cout<<"empty";
break;
}
case'c':
{
cout<<"enter your string"<<endl;
cin.get();
//cin.get();
cin.getline(palindrome,MAXSTACK);
for(int o = 0; o < strlen(palindrome); o++)
if (isalpha(palindrome[o]))
{
original.push(tolower(palindrome[o]));
stackitems++;
}
original.stack_print();
break;
}
case'd':
{
original.~stack();
for(int g = 0; g < strlen(palindrome); g++)
original.push(tolower(palindrome[g]));
original.stack_print();
}
/*//cin.getline(palindrome,MAXSTACK);
for(int g = 0; g < strlen(palindrome); g++)
if (isalpha(palindrome[g]))
{
original.push(tolower(palindrome[g]));
stackitems++;
}
}
original.stack_print();*/
break;
/*{
cout<<"original: ";
original.stack_print();
break;
}*/
break;
case'e':
{
cout<<"reversed:"<<endl;
for( i = 0; i < stackitems; i++) {
reversed.push(original.top());
original.pop();
}
reversed.stack_print();
}
break;
case'f':
{
for( i = 0; i < stackitems / 2; i++) {
reversed.push(original.top());
original.pop();
}
if (stackitems % 2)
original.pop();
while (!original.emptystack()) {
if (original.top() != reversed.top()) break;
original.pop(); reversed.pop();
}
if (original.emptystack())
cout << "it is palindrom\n";
else
cout << "not palindrom\n";
break;
}
default:cout<<"!??!";
}
} while(volba!='x');
}

You've explicitly called your stack's destructor. There is almost never a good reason to do this. If the stack is a local ("on the stack", hee hee), the compile will do it for you. If it's on the heap, created with new, call delete on it, which will cause the compiler to call the destructor.
case'd':
{
original.~stack();

You have commented palindrome reading :)
//cin.getline(palindrome,MAXSTACK);

There are a few things I would like to respond with. First, I think GMan, tpdi, and Vinay all have good points. This FAQ explains why calling the destructor on a local variable is a bad idea.
I realize this is just a simple homework problem and you are probably just trying to keep your stack class lightweight, but you might consider using a container class instead of an array of characters in your stack class.
Next, I'm not sure your emptystack and create functions are doing what you think they are doing. When you declare your original and reversed stack classes in the main program the memory is allocated for your internal character array. It's not really necessary in this case to have a create function. Perhaps if you were allocating memory on the heap for your character array, you would put that code into the create function (if you chose to leave it out of the constructor for some reason), but that's not the case here.
Similarly, emptystack isn't really doing anything. It would be better to have empty stack set the stop member variable to 0. At least that way the stack would appear to be empty the next time someone tried to use it.
There's a lot more that could be said about this class, but it might be better if you tried some of the suggestions here like using the std::stack and debugging. This is, after all, your homework assignment: it will help you a lot more in the future if you find the solution yourself!

Related

My st.show on stack cannot be display for some reason

My problem on my code is when i run it, it says the error no matching function call to stack::show() which i have. i dont know whats causing the error, did some research that it should be on the public class which already there.
I used switch case 1 is to input 2nd is to show or to display the user inputs which I cant call out using st.show();
private:
int MAX;
int top;
string *arr_q;
public:
Stack (int size)
{
MAX=size;
top=-1;
arr_q=new string[MAX];
}
void push(string subs)
{
if ((top+1)==MAX)
cout << "Stack Overflow..." << endl;
top=top+1;
arr_q[top]=subs;
}
void show(int lim)
{
int i = lim;
cout<<"Stack contains --"<<endl;
for (int ctr=i; ctr>=0; ctr--)
{
if (ctr==i)
cout<<"\t\t"<<arr_q[ctr]<<"<--Top of Stack"<<endl;
else
cout<<"\t\t"<<arr_q[ctr]<<endl;
}
}
};
case 2: {
st.show();
break;
The error is that your show function has a parameter but when you call it there is no parameter.
Seems reasonably likely that show should be written without a parameter. Like this
void show()
{
cout<<"Stack contains --"<<endl;
for (int ctr=top; ctr>=0; ctr--)
{
if (ctr==top)
cout<<"\t\t"<<arr_q[ctr]<<"<--Top of Stack"<<endl;
else
cout<<"\t\t"<<arr_q[ctr]<<endl;
}
}

Retrive data using pointers to objects in c++

This a menu based program to create a database of people and for performing operations on their name. After compilation, I am able to add a person successfully using the add function of Person class but when I retrieve the list of the added people using list function it shows garbage values instead of showing the entered names. It's the question no. 4(lab 4) in the below give doc.
https://drive.google.com/open?id=18cR9bgPlqM6q-kXBIcxg5Hpj04bkZMnW&authuser=0
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
class Person
{
const char *name;
public:
Person(const char* n)
{
name=n;
}
bool search(const char* substr)
{
const char *str=name;
while(*str!='\0')
{ int count=0;
if(*str==*substr)
{ const char *s=substr;
const char *p=str;
while(*s!='\0')
{
if(*p==*s)
{
count++;
p++;
s++;
}
else
break;
}
}
if(count==strlen(substr))
{
cout<<name<<endl;
return true;
}
str++;
}
return false;
}
void print()
{
cout<<name<<endl;
}
~Person()
{
cout << ":)";
}
friend class People;
};
class People
{
Person** array;
int length;
void prompt()
{
cout << "\n'A'-Add a person\n'L'-List all persons\n'S'-Search\n'Q'-Quit\n";
}
public:
People()
{
array = NULL;
length = 0;
}
void add()
{
string m;
cout << "Enter a Name:\n";
cin >> m;
Person s(m.c_str());
if (array == NULL)
array = (Person**)malloc(sizeof(Person*));
else
{
array=(Person**)realloc(array, length*sizeof(Person*));
}
array[length] =new Person(s.name);
array[length]->print();
++length;
}
void list()
{
cout << "\nThe names of the person in the list are:\n";
for (int i = 0; i <length; i++)
{
array[i]->print();
}
}
void search()
{
string a;
int flag = 0;
cout << "\nEnter a string to be found in the names present in the list:\n";
cin >> a;
cout << "\n The names with entered substring are:\n";
for (int i = 0; i <length; i++)
{
bool state=array[i]->search(a.c_str());
if (state)
flag = -1;
}
if (flag == 0)
cout << "\nNone of the names contains the entered substring!!!\n";
}
void menu()
{
char c = 'Y';
while (c != 'Q')
{
cout << "Choose an option(character):\n";
prompt();
cin>>c;
switch (c)
{
case 'A':add();
cout << "Name entered sucessfully!!!\n";
break;
case 'L':list();
break;
case 'S':search();
break;
case 'Q':c = 'Q';
break;
}
}
}
};
int main()
{
People All;
All.menu();
return 0;
}
I am not able to find any mistake in my implementation of add function. What could be the possible reason for malfunctioning of list function?
tl;dr
You store a pointer to the internal memory of string (m). That string gets destroyed at the end of add() so you have pointer to unallocated memory, which causes undefined behaviour.
possible solutions
Best would be to store a std::string instead of a const char * inside Person.
walkthrough
If you want a more detailed analyses: You store a pointer to a string that goes out of scope.
void add()
{
string m; // string is initialized and allocates memory for its content
cout << "Enter a Name:\n";
cin >> m; // read content
Person s(m.c_str()); // m.c_str() retrieves a pointer to the memory allocated by m
//this pointer is stored inside s
if (array == NULL)
{
array = (Person**)malloc(sizeof(Person*));
}
else
{
array=(Person**)realloc(array, length*sizeof(Person*));
}
array[length] = new Person(s.name); // s.name still points to the memory allocated by m
array[length]->print();
++length;
} //At the end of the function m gets destroyed and deallocates its memory
So after the function exits you still have stored the pointer to m.c_str() inside a persons name. This pointer now points to unallocated memory. This memory now may (or may not) be overwritten at any time. You get undefined behaviour and print garbage.

i can't get an output from this

#include<iostream>
using namespace std;
class stack
{
int size=10;
int stack[size]={0}, value=0, top;
top=size;
public:
void push(int v)
{
if(top==0)
cout<<"\nstack is full\n";
else
{--top;
stack[top]=v;}
}
void pop()
{
if(top==size)
cout<<"\nstack is empty\n";
else
{top++;
stack[top];
stack[top-1]=0;
}
}
void display()
{
if(top==size)
cout<<"\nstack empty\n";
else
{
for(int i=top;i<size-1;i++)
{
cout<<stack[i];
}
}
}
};
int main()
{
stack s;
char t;
int value,ch;
do
{
cout<<"\n1.push\n";
cout<<"\n2.pop\n";
cout<<"\n3.display\n";
cout<<"enter choice:\n";
cin>>ch;
switch(ch)
{
case 1:cout<<"\nenter the value to be pushed\n";
cin>>value;
s.push(value);
break;
case 2:s.pop();
break;
case 3:s.display();
break;
default:
cout<<"\nwrong choice\n";
}
cout<<"\ndo u want to retry\n";
cin>>t;
}while(t=='y' || t=='Y');
return 0;
}
Simplest fix to errors occurring is changing int size=10; to static const int size=10;.
After this, apart from occurring warning with stack[top]; being empty statement, there is logical error in display loop in for(int i=top;i<size-1;i++) where it should be either for(int i=top;i<size;i++) or for(int i=top;i<=size-1;i++).
As answered by Tomáš Zahradníček, you need to fix a few things to have your code compile (using -std=c++11).
I used for(int i=top; i<size; ++i) in the display method. I also add that your pop method could simply do top++; without overwriting the stack.
Anyways, regarding your problem of nothing being printed on cout : you obviously tried with 1 item pushed in the stack, but not with 2, which would have pointed to faulty line (the for loop).

segmentation fault while using two different stack of same class in a program

i just started c++ and coded a program to push and pop in 2 stacks simultaneously inn a program....i coded it corectly but while i run the program and try to access the first stack i.e s1 it shows segmentation fault but i am able access my second stack s2 very perfectly.....help me
#include<iostream>
using namespace std;
#define max 10
class stack
{
private:
int arr[max],top;
public:
void init()
{
int top=0;
}
void push(int a)
{
arr[top++]=a;
}
int pop()
{
return arr[--top];
}
int isempty()
{
if(top==0)
return 1;
else
return 0;
}
int isfull()
{
if(top==max)
return 1;
else
return 0;
}
};
int main()
{
int a,z,cas;
stack s1;
stack s2;
s1.init();
s2.init();
while(1)
{
cout<<"Enter your choice i.e. :\n";
cout<<"1.Pushing in stack s1.\n";
cout<<"2.Pushing in stack s2.\n";
cout<<"3.Poping from stack s1.\n";
cout<<"4.Poping from stack s2.\n";
cout<<"5.To STOP.\n";
cin>>cas;
switch(cas)
{
case 1:
cout<<"Enter the number to push in stack s1:\n";
cin>>a;
if(s1.isfull()==0)
s1.push(a);
else
cout<<"The Stack is full.\n";
break;
case 2:
cout<<"Enter the number to push in stack s2:\n";
cin>>a;
if(s2.isfull()==0)
s2.push(a);
else
cout<<"The Stack is full.\n";
break;
case 3:
if(s1.isempty()==0)
cout<<"The number poped out is :\n"<<s1.pop()<<endl;
else
cout<<"The stack is empty.\n";
break;
case 4:
if(s2.isempty()==0)
cout<<"The number poped out is :\n"<<s2.pop()<<endl;
else
cout<<"The stack is empty.\n";
break;
case 5:
cout<<"The elements in stack s1 are :\n";
while(!s1.isempty())
cout<<s1.pop()<<" ";
cout<<endl;
cout<<"The elements in stack s2 are :\n";
while(!s2.isempty())
cout<<s2.pop()<<" ";
cout<<endl;
exit(1);
}
}
return 0;
}
Much more useful than a debugger is the art of reading carefully:
void init()
{
int top=0;
}
declares a local variable top.
The member variable is left uninitialised, leading to Undefined Behaviour.
That one of the stacks appears to work is just bad luck.
Making it a proper assignment:
void init()
{
top=0;
}
would do it, but this is C++, so you should use a constructor:
class stack
{
public:
stack();
// ...
};
stack::stack()
: top(0)
{
}
and then
stack s1;
stack s2;
while(1)
{
// ...

Messy and wrong char visualization (after passing actual parameters) C++

this is my first post. Below the code of my implementation of a char Stack. Theoretically It should print f,g,h. But when I execute it, I can just see a long list of strange signs in the console. Is a compiler issue or code issue? Thanks.
#include <iostream>
using namespace std;
const int max_L = 10;
class Stack {
protected:
char array[];
int length;
public:
Stack(){length = 0;}
bool push(char c) {
if(length < max_L){
array[length] = c;
length++;
return(true);
}
else return(false);
}
void pop(){
if(length >= 1){
cout << array[length];
length--;
} else return ;
}
bool is_empty(){
return(length == 0);
}
void print(){
for(int i = 0; i < length; i++){
cout << array[i];
}
}
};
int main() {
Stack p1;
p1.push('f');
p1.push('g');
p1.push('h');`
p1.print();
return 0;
}
There are two problems in the code. As πάντα ῥεῖ said, the array has to be created with a size. The other problem is that push and pop aren't quite complementary. push puts the added value at array[length], then increments length. So after a call to push, length is the index of the next entry, i.e., the one that hasn't been put in yet. pop has to look at the previous entry, i.e., the one that was just put in. So the code for pop should decrement length before looking at array[length]. Change
cout << array[length];
length--;
to
length--;
cout << array[length];