Ok I'm doing my final project for my Data Structures class and have a quick question. This hasn't come up in any of my programming classes yet (which now that I think about it, is kind of odd but oh well).

What I'm having to do is write an interactive program allowing the user to access 3 different data structures. That part I have no problems with (going to use Stacks, Queues & Binary Tree). What I'm wanting is to have the main menu display:

1) Use Stacks
2) Use Queues
3) Use Binary Tree
4) Exit Program

then it goes into the submenu for that option.

What I need is to reset the program so when they finish with that data structure it brings them back to the main menu.

Here is what I'm thinking should work, am I right or do I need to go about it differently?

do
{
    " Display main menu here"

      if (option 1 is picked)
       {
           do
              {
                 "Display menu for selection"
                 run program
              }
              while (user does not select to exit)
        }

      if (option 2 is picked)
       {
          do
             {
                "same as option 1"
              }
          while (user doesnt select to exit)
       }

}
while (user doesn't select to quit entire program)

Now before everyone starts to nit pick at my code, it's just a shell to give you an idea of what I want to do.


Thanks

Perhaps consider a menu using a switch case construction?

Ok I decided that to organize the main menu better and make the code look nicer I went with the switch commands. But that doesn't resolve my initial problem. When I for example select stacks, I can do whatever I want within that piece of the program, but as soon as I choose to exit, it completely exits the entire program. I want it to revert back to my main menu.

It's not a requirement, but I'm aiming for a 100%, that'll give me a 89% in the class.

If you don't want to exit don't use the function exit() which will terminate the program.

sentinel set to not done
while not done:
      menu options:
      switch:
      option 1:
           do this and break
      option 2:
           do this and break
      option 3:
          I am done set sentinel to done.
continue flow of program

well...this thing also depends on how the menus and submenus are structured.
For example...i have faced a situation in which..i need to first select an object on which i need to perform certain operations...which are,in turn, same for all the objects..
Thus, i would definitely have a structure..in which..i have the main menu which gives options to select an object..and then i move to another menu (which i may/ may not consider submenu) which gives choices for the operations.. :)

another situation is obvious..which..i think you are facing..

anyways..i have attached a program which deals with both the situations..
have a look on it if u want to. :)
NOTE : its a CPP (and hence an OO) program..Also the graphics.h header file of Borland Turbo C++ i have used is very much primitive..so i think the code wont work..unless you use Turbo C++...
however..i dont think thats your concern...so hope this helps you.. :)
gud luck..

Attachments
#include <iostream.h>
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>

class Menu
{
private :
	int selectedOption;

public :
	Menu()
	{
		selectedOption = -1;
	}
	void selectObject(void);
	void selectTransformation(void);
	void selectRotation(void);
	void selectScaling(void);
	void selectShearing(void);
	void selectReflection(void);
	int& getSelectedOption(void)
	{
		return selectedOption;
	}
};

void Menu::selectObject(void)
{
	clrscr();
	cout << "1. Point."    << endl
			 << "2. Line."  	 << endl
			 << "3. Triangle." << endl
			 << "0. Exit."     << endl
			 << "Select the object on which you want to perform transformation : ";

	cin >> selectedOption;
}

void Menu::selectTransformation(void)
{
		clrscr();
		cout << "1. Translation." << endl
				 << "2. Rotation."    << endl
				 << "3. Scaling."     << endl
				 << "4. Reflection."  << endl
				 << "5. Shearing."    << endl
				 << "0. Exit to object selection menu." << endl;

		cout << "Select the transformation you want to perform : ";
		cin  >> selectedOption;
}

void Menu::selectRotation(void)
{
	clrscr();
	cout << "Rotation about :"                 << endl
			 << "1. Origin."        							 << endl
			 << "2. Pivot point." 								 << endl
			 << "0. Exit to transformation menu."  << endl;

	cout << "Enter your choice : ";
	cin  >>  selectedOption;
}

void Menu::selectScaling(void)
{
	clrscr();
	cout << "Scaling with respect to :" 			<< endl
			 << "1. Origin." 											<< endl
			 << "2. Fixed point." 								<< endl
			 << "0. Exit to transformation menu." << endl;

	cout << "Enter your choice : ";
	cin  >> selectedOption;
}

void Menu::selectReflection(void)
{
	clrscr();
	cout << "Reflection about : " << endl
			 << "1. X-axis."          << endl
			 << "2. Y-axis."          << endl
			 << "3. XY-plane."        << endl
			 << "0. Exit to transformation menu." << endl;

	cout << "Enter your choice : ";
	cin  >> selectedOption;
}

void Menu::selectShearing(void)
{
	clrscr();
	cout << "Shearing on : " 																				 << endl
			 << "1. X-axis."     																				 << endl
			 << "2. Y-axis."                   													 << endl
			 << "3. X-axis with respect to a reference point on Y-axis." << endl
			 << "4. Y-axis with respect to a reference point on X-axis." << endl
			 << "0. Exit."                                               << endl;

	cout << "Enter your choice : ";
	cin  >> selectedOption;
}


class GraphicSystem
{
private :
	int graphicDriver, graphicMode, maxX, maxY, errorCode;

public :
	GraphicSystem();
	void setViewPort();

	void switchToGraphicMode()
	{
		setgraphmode(getgraphmode());
	}

	void switchToTextMode()
	{
		restorecrtmode();
	}

	void setLineStyleColor (int lineStyle, int color)
	{
		setlinestyle (lineStyle, 1, 1);
		setcolor (color);
	}

	~GraphicSystem()
	{
		closegraph();
	}

};

GraphicSystem::GraphicSystem()
{
	graphicDriver = DETECT;
	initgraph (&graphicDriver, &graphicMode, "c:\\tc\\bgi");
	errorCode = graphresult();
	if (errorCode != 0)
	{
		cout << "Graphics error : " << grapherrormsg (errorCode) << endl;
		cout << "Press any key to terminate..";
		cin.ignore();
		cin.get();
	}
	maxX = getmaxx();
	maxY = getmaxy();
}

void GraphicSystem::setViewPort()
{
	switchToGraphicMode();
	line (0, maxY/2, maxX, maxY/2);
	line (maxX/2, 0, maxX/2, maxY);
	setviewport (maxX/2, maxY/2, maxX, maxY, 0);
}


// base class Object
class Object
{
protected :
	int* referencePoint_;

public :
	Object()
	{
		referencePoint_  = new int [2];
		*(referencePoint_ + 0) = *(referencePoint_ + 1) = 0;
	}

	void setReferencePoint(int *pointCoords)
	{
		*(referencePoint_ + 0) = *(pointCoords+0);
		*(referencePoint_ + 1) = *(pointCoords+1);
	}

	void plotReferencePoint() const
	{
		putpixel (referencePoint_[0], referencePoint_[1], RED);
	}

	virtual void translate (float& tx, float& ty) = 0;
	virtual void rotate (float& angle) = 0;
	virtual void scale (float& , float& ) {}
	virtual void reflect(int, int) = 0;
	virtual void shear(float&, float&) {}
	virtual void draw (void) const = 0;
	virtual void setCoords (int* coords) = 0;
	virtual int* getCoords (void) const = 0;

	virtual ~Object()
	{
		delete [] referencePoint_;
	}
};


// Point class
class Point : public Object
{
private :
	int* coords_;

public :
	Point() : Object()
	{
		coords_ = new int[2];
	}

	~Point()
	{
		delete [] coords_;
	}

	void setCoords (int* coords)
	{
		coords_[0] = coords[0];
		coords_[1] = coords[1];
	}

	int* getCoords (void) const
	{
		return coords_;
	}

	void translate (float& tx, float& ty)
	{
		coords_[0] += tx;
		coords_[1] += ty;
	}

	void rotate (float& angle);

	void reflect (int xValue, int yValue)
	{
		coords_[0] *= xValue;
		coords_[1] *= yValue;
	}

	void draw(void) const
	{
		putpixel (coords_[0], coords_[1], GREEN);
	}

};

void Point::rotate (float& angle)
{
	// here using a single temporary variable wont work..because we need to
	// retain the value of coords_[0], which otherwise couldnt have been
	// maintained.
	int newX, newY;

	//x' = x*cos(angle) - y*sin(angle)
	//y' = y*cos(angle) + x*sin(angle)
	//x' = xref + (x - xref) * cos(angle) - (y - yref) * sin(angle);
	//y' = yref + (y - yref) * cos(angle) + (x - xref) * sin(angle);

	newX = referencePoint_[0] + (coords_[0] - referencePoint_[0]) * cos(angle)
														- (coords_[1] - referencePoint_[1]) * sin(angle);

	newY = referencePoint_[1] + (coords_[1] - referencePoint_[1]) * cos(angle)
														+ (coords_[0] - referencePoint_[0]) * sin(angle);

	coords_[0] = newX;
	coords_[1] = newY;
}


// Line class
class Line : public Object
{
private :

	int* coords_;

public :
	Line() : Object()
	{
		coords_ = new int[4];
	}

	~Line()
	{
		delete [] coords_;
	}

	void setCoords (int* coords);
	void translate (float& tx, float& ty);
	void rotate (float& angle);
	void scale (float& sx, float& sy);
	void reflect (int xValue, int yValue);

	int* getCoords (void) const
	{
		return coords_;
	}

	void draw(void) const
	{
		line (coords_[0], coords_[1], coords_[2], coords_[3]);
	}

};

void Line::setCoords (int* coords)
{
	coords_[0] = coords[0];
	coords_[1] = coords[1];
	coords_[2] = coords[2];
	coords_[3] = coords[3];
}

void Line::translate (float& tx, float& ty)
{
	coords_[0] = coords_[0] + tx;
	coords_[1] = coords_[1] + ty;
	coords_[2] = coords_[2] + tx;
	coords_[3] = coords_[3] + ty;
}

void Line::rotate (float& angle)
{

	int newX, newY;

	for (int i = 0; i < 4; i += 2)
	{
		newX = referencePoint_[0]
								+ (coords_[i] - referencePoint_[0]) * cos(angle)
								- (coords_[i+1] - referencePoint_[1]) * sin(angle);

		newY = referencePoint_[1]
								+ (coords_[i] - referencePoint_[0]) * sin(angle)
								+ (coords_[i+1] - referencePoint_[1]) * cos(angle);

//		temp1 = coords_[i] * cos(angle) - coords_[i+1] * sin(angle);
//		temp2 = coords_[i+1] * cos(angle) + coords_[i] * sin(angle);
		coords_[i] = newX;
		coords_[i+1] = newY;
	}
}

void Line::scale (float& sx, float& sy)
{
	for (int i = 0; i < 2; i += 2)
	{
		coords_[i]   = referencePoint_[0] + (coords_[i] - referencePoint_[0])
									 * sx;
		coords_[i+1] = referencePoint_[1] + (coords_[i+1] - referencePoint_[1] )
									 * sy;
	}
}

void Line::reflect (int xValue, int yValue)
{
	coords_[0] *= xValue;
	coords_[1] *= yValue;
	coords_[2] *= xValue;
	coords_[3] *= yValue;
}



// Triangle class
class Triangle : public Object
{
private :
	int* coords_;

public :
	Triangle() : Object()
	{
		coords_ = new int[8];
	}

	virtual ~Triangle()
	{
		delete [] coords_;
	}

	void setCoords (int* coords);
	void translate (float& tx, float& ty);
	void rotate (float& angle);
	void scale (float& sx, float& sy);
	void reflect (int xValue, int yValue);
	void shear (float& shx, float& shy);

	int* getCoords (void) const
	{
		return coords_;
	}

	void draw(void) const
	{
		drawpoly (4, coords_);
	}

};

void Triangle::setCoords (int* coords)
{
	for (int i=0; i < 6; i+= 2)
	{
		coords_[i] = coords[i];
		coords_[i+1] = coords[i+1];
	}
	coords_[6] = coords_[0];
	coords_[7] = coords_[1];
}

void Triangle::translate (float& tx, float& ty)
{
	for (int i = 0; i < 6; i+=2)
	{
		coords_[i]   = coords_[i]   + tx;
		coords_[i+1] = coords_[i+1] + ty;
	}
	coords_[6] = coords_[0];
	coords_[7] = coords_[1];
}

void Triangle::rotate (float& angle)
{
	int newX, newY;
	for (int i = 0; i < 6; i += 2)
	{
//		temp1 = coords_[i] * cos(angle) - coords_[i+1] * sin(angle);
//		temp2 = coords_[i+1] * cos(angle) + coords_[i] * sin(angle);
		newX = referencePoint_[0]
					 + (coords_[i] - referencePoint_[0]) * cos(angle) - (coords_[i+1]
					 - referencePoint_[1]) * sin(angle);

		newY = referencePoint_[1]
					 + (coords_[i] - referencePoint_[0]) * sin(angle)
					 + (coords_[i+1] - referencePoint_[1]) * cos(angle);

		coords_[i] = newX;
		coords_[i+1] = newY;
	}
	coords_[6] = coords_[0];
	coords_[7] = coords_[1];
}

void Triangle::scale (float& sx, float& sy)
{
	for (int i = 0; i < 6; i += 2)
	{
		coords_[i]   = referencePoint_[0] + (coords_[i] - referencePoint_[0])
									 * sx;
		coords_[i+1] = referencePoint_[1] + (coords_[i+1] - referencePoint_[1])
									 * sy;
	}
	coords_[6] = coords_[0];
	coords_[7] = coords_[1];
}

void Triangle::reflect (int xValue, int yValue)
{
	for (int i = 0; i < 6; i += 2)
	{
		coords_[i]   *= xValue;
		coords_[i+1] *= yValue;
	}
	coords_[6] = coords_[0];
	coords_[7] = coords_[1];
}

void Triangle::shear (float& shx, float& shy)
{
	int newX, newY;
	for (int i = 0; i < 6; i+=2)
	{
		newX = coords_[i]       + coords_[i+1] * shx - shx * referencePoint_[1];
		newY = coords_[i] * shy + coords_[i+1]       - shy * referencePoint_[0];

		coords_[i]   = newX;
		coords_[i+1] = newY;
	}
	coords_[6] = coords_[0];
	coords_[7] = coords_[1];
}



// main function
in

A comment if I may bhoot_jb.

another situation is obvious..which..i think you are facing..

You make heavy use of [..]. I know what ellipsis are [...], but I can't figure what's the process that warrant the use of two consecutive periods.

gud luck..

What's the advantage of misspelling "good" to just save the writing of one more vowel?
Why not "gu luc"? That seems to me more advantageous. Better yet, "guluc" will save even the space.
Of course, all is for naught because of the mysterious two periods afterward.

A comment if I may bhoot_jb.


You make heavy use of [..]. I know what ellipsis are [...], but I can't figure what's the process that warrant the use of two consecutive periods.


What's the advantage of misspelling "good" to just save the writing of one more vowel?
Why not "gu luc"? That seems to me more advantageous. Better yet, "guluc" will save even the space.
Of course, all is for naught because of the mysterious two periods afterward.

lolz. OK. thanks for pointing out my mistakes. Actually i was used to such typing in this weird way in mobile chatting. :) There is nothing special about using two consecutive periods or ellipsis. :)
And as far as "gud luck" is concerned, its almost the same issue, i.e., i make a heavy use of short spellings. :| i have been warned earlier against using such short spellings.
However i have improved much better and will do the same in future. :)
Now, this is going off-topic. So i better conclude. :)

Comments
For taking it the right way.

There's a few solutions to that 'problem'. I usually try and keep the clutter out of main by putting all the meat and bones of main() into functions and only using main to call them, and potentially have a loop (which would return you to the first menu for example). This, however, is a bit worse for resources than using a switch statement with all the code inside of each case. I, personally, would be more conscerned with getting the binary tree working :P

There's a few solutions to that 'problem'. I usually try and keep the clutter out of main by putting all the meat and bones of main() into functions and only using main to call them, and potentially have a loop (which would return you to the first menu for example). This, however, is a bit worse for resources than using a switch statement with all the code inside of each case. I, personally, would be more conscerned with getting the binary tree working :P

Actually all of my data structures function in their seperate programs (including the binary tree). I created a pointer to the submenu on main within the switch statements: i.e

switch (m_select)
case 1:
{
stackmenu();
break;
}

I ran the program and the stack program is complete and functions correctly (except when I exit, it proceeds to crash, but thats not important at the moment).

So if I call the menus up within the switch statements how would I get those sub menus to terminate and return to the actual main menu?

Here is my main menu code (seeing what I have may help)

#include "binaryTreeSearch.h"
#include "mystack.h"
#include "queuetype.h"
#include "menu_display.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{
	int m_select;
	menu_display menu;

	cout << "Final Project Program" << endl;
	cout << endl;
	cout << "1) Stack Data Structures" << endl;
	cout << "2) Queue Data Structures" << endl;
	cout << "3) Binary Tree Data Structures" << endl;
	cout << "4) End Program" << endl;
	cout << endl;
	cout << "Please make selection: ";
	cin >> m_select;
	
	switch (m_select)
	{
	case 1:
		menu.s_display();
	break;

	case 2:
		menu.q_display();
	break;

	case 3:
		menu.b_display();
	break;

	case 4:
		cout << "Now exiting program.\n";
	break;

	default:
		cout << "Invalid selection.\n";
	break;
	}


}

And here is my stack program (some of it)

void menu_display::s_display()
{
	int select;
	
	//generate main welcome screen
	cout << "Welcome to my stack program. "<<endl;
	cout << "Please select what type of stack you want. "<<endl;
	cout << "1 - Int stack" <<endl;
	cout << "2 - String stack" <<endl;
	cout << "3 - Quit Program" <<endl;
	cin >> select; //user selects option

	if (select == 1)
	{
		int amount;
		int num;
		int choice;
		int j = 0;

		cout << "How many INT stacks do you want? ";
		cin >> amount;
		//create int stack (1 original, 1 for copy & 1 to work with)
		mystack<int> intStack(amount);
		mystack<int> copyStack(amount);
		mystack<int> workStack(amount);

		intStack.initializeStack(); //set original stack to 0
		cout <<endl;
	do
	{
		//prompt for functions to do with the stack
		cout << "Make selection." <<endl;
		cout << "1 - Add to stack." <<endl;
		cout << "2 - Display top of stack." <<endl;
		cout << "3 - Remove item from stack." <<endl;
		cout << "4 - Copy stack." <<endl;
		cout << "5 - Quit Program." <<endl;
		cin >> choice;

		if (choice == 1)
		{
			//add items to stack until "j" reaches amount user previously inputted
			cout << "Input your values pressing Enter after each one" <<endl;

			do
			{
				cin >> num;
				intStack.push(num);
				j++;
			}
			while(j < amount);
			workStack = intStack;
		}

		if (choice == 2)
		{
			//display contents of stack until end is reached
			copyStack = intStack;
			cout << "The stack elements are: ";
			while(!copyStack.isEmptyStack())
			{
				cout<< copyStack.top() <<" ";
				copyStack.pop();
			}
			cout << endl;
		}

		if (choice == 3)
		{
			//remove top item from stack
			cout << "Removing top element.";
			intStack.pop();
		}

		if (choice == 4)
		{
			//display content of original stack until end is reached
			copyStack = workStack;
			cout << "The original stack is: ";
			while(!workStack.isEmptyStack())
			{			
				cout << workStack.top() <<" ";
				workStack.pop();
			}
			cout << endl;
			//display content of copied stack until end is reached
			cout << "The copied stack is: ";
			while(!copyStack.isEmptyStack())
			{
				cout << copyStack.top() <<" ";
				copyStack.pop();
			}
			cout << endl;
		}

	}
	while(choice != 5); //keep displaying menu options until "5" is selected
	//clear memory used by stacks
	intStack.~mystack();
	copyStack.~mystack();
	workStack.~mystack();

	}

I am going to try to answer this, but I don't completely understand your problem.

Your function s_display() will process the stack routine and then return back to the switch statement in your main(). If you want to continue asking the user to process a different data structure type after processing the stack, you need something like this.

int main()
{
  int m_select;
  bool done = false;

  while (!done){

    cout << "Final Project Program" << endl;
    cout << endl;
    cout << "1) Stack Data Structures" << endl;
    cout << "2) Queue Data Structures" << endl;
    cout << "3) Binary Tree Data Structures" << endl;
    cout << "4) End Program" << endl;
    cout << endl;
    cout << "Please make selection: ";
    cin >> m_select;

    switch (m_select)
    {
    case 1:
      cout << "calling stack.\n";
      s_display();
      break;

    case 2:
      cout << "calling queue \n"; 
      menu.q_display();
      break;

    case 3:
      cout << "calling bintree \n"; 
      menu.b_display();
      break;

    case 4:
      done = true;
      cout << "Now exiting program.\n";
      break;

    default:
      done = true;
      cout << "Invalid selection.\n";
      break;
    }
  }

}

Also you probably want to replace all the "if's" by switch statements in your display() functions.

I'll clean up the code tomorrow, and I'll try the while command. I was thinking of the do/while but am unsure if while in the sub-menus if they'll quit back to the main one or not. I'll update tomorrow when I try it.

This question has already been answered. Start a new discussion instead.