For some reason, I cannot get the testLisp function to work correctly within the while loop in processRequest(). No matter where I put testLisp within the while loop (even outside of the if-statements), it will ask to input an expression and automatically give a segmentation fault before the user can enter anything. testLisp works correctly when called in main, or when it is called outside the while loop in processRequest().
testStacks() works fine when called in the while loop.
Can anybody please help?
If you need the cstack file, I can provide that, too.
//@author snazzy
//@date 3/5/10 last modified 3/5/10
//@file cstack.cpp
//@Specification for Abstract Data Type Stack:
// data object: a stack of items (Last-In-First-Out list of items)
// operations: Create. Copy, Destroy (constructors and destructor)
// Push and Pop (insert and delete at 'the top')
// GetTop (retrieve 'the top'), IsEmpty
#include "cstack.h"
#include <cstdlib>
#include <iostream>
usingnamespace std;
struct NodeType
{
ItemType info;
NodeType* next;
};
//@Initializes an empty stack
//@post: the class object is empty
//@usage: StackType stk;
StackType::StackType()
{
topptr = NULL;
}
//@Copies the stack object s to the class object
//@pre: rhs_stk exists
//@post: the class object has the same contents in same order as rhs_stk
//@param rhs_stk
//@sage: StackType stk2 (stk1);
StackType::StackType (const StackType& rhs_stk)
{
if (rhs_stk.IsEmpty())
{
topptr = NULL;
} else {
topptr = NULL;
topptr = new(nothrow) NodeType;
NodeType* topcurptr = topptr;
NodeType* rhscurptr = rhs_stk.topptr;
topcurptr -> info = rhscurptr -> info;
topcurptr -> next = NULL;
rhscurptr = rhscurptr -> next;
while(rhscurptr != NULL)
{
topcurptr -> next = new(nothrow) NodeType;
topcurptr = topcurptr -> next;
topcurptr -> info = rhscurptr -> info;
topcurptr -> next = NULL;
rhscurptr = rhscurptr -> next;
}
}
}
//@Destroys the class object
//@pre: class object exists
//@post: class object no longer exists
//@usage: automatically done at exit of the module in which declared
StackType::~StackType()
{
bool ok;
//while(!IsEmpty())
//Pop(ok);
}
//@Determines whether or not a stack is empty
//@pre: class object exists
//@post: returns true if class empty is empty; else returns false
//@return true or false
//@usage: if (stk.IsEmpty())
bool StackType::IsEmpty() const
{
return(topptr == NULL);
}
//@Adds a new item to the top of a stack
//@pre: class object exists
//@post: If class object is not full, then
// adds newItem at the top of the class object and
// ok is true else ok is false
//@param newItem
//@param ok
//@usage: stk.Push (4, ok);
void StackType::Push (ItemType newItem, bool& ok)
{
NodeType* newptr;
newptr = new(nothrow) NodeType;
if(newptr != NULL)
{
ok = true;
newptr -> info = newItem;
newptr -> next = topptr;
topptr = newptr;
}
else
ok = false;
}
//@Deletes the top item from a stack
//@pre: class object exists
//@post: If class object was not empty, ok is true and the post-
// object is without top item of the pre-object;
// else ok is false
//@param ok
//@usage: stk.Pop(ok);
void StackType::Pop (bool& ok)
{
NodeType* delptr;
if(!IsEmpty())
{
ok = true;
delptr = topptr;
topptr = topptr -> next;
delptr -> next = NULL;
delete delptr;
ok = false;
}
else
ok = false;
}
//@Copies the top item of a stack
//@pre: class object exists
//@post: If object is not empty, theTop contains the top item of
// object and ok is true; else ok is false
//@param theTop
//@param ok
//@usage stk.GetTop(top,ok);
void StackType::GetTop (ItemType& theTop, bool& ok)
{
if(IsEmpty())
ok = false;
else
{
ok = true;
theTop = topptr -> info;
}
}
//@directs program to correct function(s) based
//@ on user's choice
//@pre choice is given by user
//@usage processRequest);
void processRequest()
{
int choice, size;
choice = printMenu();
while (choice != 3)
{
if (choice == 1)
{
cout << "How big would you like to make the stack? -> ";
cin >> size;
cout << endl;
testStacks(size);
} elseif (choice == 2) {
testLisp();
}
choice = printMenu();
}
}
This one works properly when called outside of the while loop, but not within the while loop, no matter where within the while loop. It will give a segmentation fault and exits the program before the user can enter anything.
//@tests the Lisp function
//@post prints if the expression is balanced or not
//@usage testLisp();
void testLisp()
{
char symbol, openSymbol;
char line[100];
int i = 0;
StackType stk;
bool balanced = true;
bool ok;
cout << "Enter an expression and press return: ";
cin.getline(line, 100, '\n'); //I couldn't get cin.get to work
while (line[i] != '\n' && balanced)
{
if (IsOpen(line[i]))
{
stk.Push(line[i], ok);
}
elseif (IsClosed(line[i]))
{
if (stk.IsEmpty())
balanced = false;
else
{
ItemType top;
stk.GetTop(top, ok);
stk.Pop(ok);
openSymbol = top;
balanced = Matches(line[i], openSymbol);
}
}
i++;
}
if (balanced && stk.IsEmpty())
cout << "Expression is well formed." << endl;
else
cout << "Expression is not well formed." << endl;
}
These are the menu choices:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//@prints the main menu, will loop until '3' is entered
//@post menu is printed, answer is returned
//@return answer = '1', '2', or '3'
//@usage choice = printMenu();
int printMenu()
{
int choice;
cout << "What would you like to do?" << endl;
cout << "1 - Test stack functions" << endl;
cout << "2 - Test LISP" << endl;
cout << "3 - Exit" << endl;
cout << "-> ";
cin >> choice;
return choice;
}
Main: If I were to uncomment testLisp(), it works fine.
1 2 3 4 5 6 7 8 9
int main()
{
printIntro();
//testLisp();
processRequest();
thankPlayer();
return 0;
}
//@author snazzy
//@date 3/5/10 last modified 3/5/10
//@file cstack.h
//@Specification for Abstract Data Type Stack:
// data object: a stack of items (Last-In-First-Out list of items)
// operations: Create. Copy, Destroy (constructors and destructor)
// Push and Pop (insert and delete at 'the top')
// GetTop (retrieve 'the top'), IsEmpty
#ifndef STACKTYPE_H
#define STACKTYPE_H
typedefint ItemType;
struct NodeType;
class StackType
{
public:
//@Initializes an empty stack
//@post: the class object is empty
//@usage: StackType stk;
StackType();
//@Copies the stack object s to the class object
//@pre: rhs_stk exists
//@post: the class object has the same contents in same order as rhs_stk
//@param rhs_stk
//@sage: StackType stk2 (stk1);
StackType (const StackType& rhs_stk);
//@Destroys the class object
//@pre: class object exists
//@post: class object no longer exists
//@usage: automatically done at exit of the module in which declared
~StackType();
//@Determines whether or not a stack is empty
//@pre: class object exists
//@post: returns true if class empty is empty; else returns false
//@return true or false
//@usage: if (stk.IsEmpty())
bool IsEmpty() const;
//@Adds a new item to the top of a stack
//@pre: class object exists
//@post: If class object is not full, then
// adds newItem at the top of the class object and
// ok is true else ok is false
//@param newItem
//@param ok
//@usage: stk.Push (4, ok);
void Push (ItemType newItem, bool& ok);
//@Deletes the top item from a stack
//@pre: class object exists
//@post: If class object was not empty, ok is true and the post-
// object is without top item of the pre-object;
// else ok is false
//@param ok
//@usage: stk.Pop(ok);
void Pop (bool& ok);
//@Copies the top item of a stack
//@pre: class object exists
//@post: If object is not empty, theTop contains the top item of
// object and ok is true; else ok is false
//@param theTop
//@param ok
//@usage stk.GetTop(top,ok);
void GetTop (ItemType& theTop, bool& ok);
private:
NodeType* topptr;
};
#endif
I had to do what I said earlier and do this: while (line[i] != 0 && balanced) //test against end of string null terminator
Also on my system cin.getline was picking up a leftover '\n' from the buffer and would not wait for user input and end up with an empty line. So if you find that happening the add cin.ignore
like this:
1 2 3 4
cout << "Enter an expression and press return: ";
cin.ignore(); //You may need this
cin.getline(line, 100, '\n'); //I couldn't get cin.get to work
while (line[i] != 0 && balanced)