Cannot Call Function in While Loop

This code is due very soon, so quick help would be much appreciated.

Here is the URL:
http://codeviewer.org/view/code:c98

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.
Last edited on
Can you post code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//@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>
using namespace 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;
	}
}
Can't see a getLisp function
Sorry, I thought you wanted cstack.cpp. Here are the functions I need help on

Here is the function with the troublesome while loop.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//@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);
		} else if (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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//@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);
		}
		else if (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;
}


Any other code you need?

Thank you!
I think you have a problem in testlisp function here:
1
2
	cin.getline(line, 100, '\n'); //I couldn't get cin.get to work
	while (line[i] != '\n' && balanced) //<<===== here 


The '\n' character is the delimiter - it is not actually kept. Try:

while (line[i] != 0 && balanced) //test against end of string null terminator


If you post cstack.h - I will be able to run the program and check.
Last edited on
It's strange because testLisp() works fine when called directly in main, but not when it is inside of a while loop.

cstack.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//@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

typedef int 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 
Oops and cstack cpp - and I'll be ready to go
cstack.cpp is in the third post from the top. :)
Oops, in cstack.cpp, in the destroy command StackType::~StackType(), go ahead and uncomment everything within it. Shouldn't affect anything too much.
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)
Thank you very much for your help. This is definitely something I couldn't have figured out on my own.

I think my cin.getline was getting a leftover '\n' too. Any idea why that is?
Topic archived. No new replies allowed.