CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Feb 2009
    Posts
    135

    Program Loops going wrong?

    Alright, so here are the specific culprits:

    Code:
    bool Do_Main(int& Command, vector<Student_Record>& student)
    {
    	enum Menu_Options
    	{
    		ADD_STUDENT, LIST_STUDENT, EXIT
    	};
    
    	--Command;
    
    	switch (Command)
    	{
    		case ADD_STUDENT:
    			while(AddStudent_Menu(student))
    			//break;
    		case LIST_STUDENT:
    			cout << endl << "You chose Do_ListStudent();" 
    				 << endl; //Do_ListStudent();
    			return true;
    			//break;
    		case EXIT:
    			cout << endl << "You chose Do_Exit();" 
    				<< endl; //Do_Exit();
    			return false;
    			//break;
    	}
    }
    Code:
    bool Do_AddStudent(vector<Student_Record>& student, int Command)
    {
    	enum Menu_Options
    	{
    		NAME, MIDTERM, FINAL, HOMEWORK, TESTS, QUIZZES,
    		PROJECTS, EXIT
    	};
    
    	--Command;
    
    	switch (Command)
    	{
    		case NAME:
    			cout << endl << "getline(cin, student.name);"
    				 << endl;
    			return true;
    			//break;
    		case MIDTERM:
    			cout << endl << "student.midterm = GetIntInput()" 
    				 << endl;
    			return true;
    			//break;
    		case FINAL:
    			cout << endl << "student.final = GetIntInput()"
    				 << endl;
    			return true;
    			//break;
    		case HOMEWORK:
    			cout << endl << "Add-Edit_Homework();"
    				<< endl;
    			return true;
    			//break;
    		case TESTS:
    			cout << endl << "Add-Edit_Tests();"
    				 << endl;
    			return true;
    			//break;
    		case QUIZZES:
    			cout << endl << "Add-Edit_Quizzes();"
    				 << endl;
    			return true;
    			//break;
    		case PROJECTS:
    			cout << endl << "Add-Edit_Projects();"
    				 << endl;
    			return true;
    			//break;
    		case EXIT:
    			return false;
    			//break;
    		}
    }
    Whole Program:
    grader.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include "graderIO.h"
    #include "Student_Record.h"
    #include "Menu.h"
    
    using namespace std;
    
    typedef string::size_type sz_t;
    
    int main()
    {
    	vector<Student_Record> student;
    
    	while(Main_Menu(student))
    
    	return 0;
    }
    graderIO.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <iomanip>
    #include "graderIO.h"
    #include "Student_Record.h"
    #include "Menu.h"
    
    using namespace std;
    
    typedef string::size_type sz_t;
    
    // ParseInt() by Russco
    bool ParseInt( const string& input, double& retval )
    {
        istringstream parsed_string( input );
        if( parsed_string >> retval )
            return true;
        else
            return false;
    }
    
    // GetIntInput() by Russco, modified by BleaS
    double GetIntInput( const string& message, string error = "\nYour input is invalid, please try again.\n\n", double min_accepted = INT_MIN, double max_accepted = INT_MAX)
    {
        std::string input;
        double retval;
        int not_first = 0;
       do
       {
          if (not_first == 1)
          {
              cout << error;
          }
          std::cout << message;
          std::getline( cin, input );
          not_first = 1;
       } while ( !ParseInt( input, retval ) || retval < min_accepted || retval > max_accepted );
       return retval;
    }
    
    bool Do_Main(int& Command, vector<Student_Record>& student)
    {
    	enum Menu_Options
    	{
    		ADD_STUDENT, LIST_STUDENT, EXIT
    	};
    
    	--Command;
    
    	switch (Command)
    	{
    		case ADD_STUDENT:
    			while(AddStudent_Menu(student))
    			//break;
    		case LIST_STUDENT:
    			cout << endl << "You chose Do_ListStudent();" 
    				 << endl; //Do_ListStudent();
    			return true;
    			//break;
    		case EXIT:
    			cout << endl << "You chose Do_Exit();" 
    				<< endl; //Do_Exit();
    			return false;
    			//break;
    	}
    }
    Menu.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <iomanip>
    #include "Menu.h"
    #include "graderIO.h"
    #include "Student_Record.h"
    
    using namespace std;
    
    typedef string::size_type sz_t;
    
    void AddPrefix(vector<string>& MenuOption)
    {
        int count = 1;
    
        for (vector<string>::iterator iter = MenuOption.begin(), end = MenuOption.end();
            iter != end; ++iter)
        {
            stringstream is;
    		is << count << "." << ((count < 10) ? "  " : " ") << *iter;
            *iter = is.str();
            ++count;
        }
    }
    
    sz_t FindMaxWidth(const vector<string>& MenuOption)
    {
    	sz_t Size = MenuOption.size(), Max_Width = 0;
            vector<string>::const_iterator iter;
    
    	for (iter = MenuOption.begin(); iter != MenuOption.end(); ++iter)
    	{
    		if (iter->size() > Max_Width)
    		{
    			Max_Width = iter->size();
    		}
    	}
    
    	return Max_Width;
    }
    void WriteMenu(vector<string>& MenuOption, 
    			   sz_t MenuWidth, sz_t MenuHeight, 
    			   sz_t BorderCol = 1, sz_t BufferCol = 0,
    			   sz_t BorderRow = 1, sz_t BufferRow = 0)
    {
    	int T_BorderCol = BorderCol * 2, T_BorderRow = BorderRow * 2,
    		T_BufferCol = BufferCol * 2, T_BufferRow = BufferRow * 2,
    	    T_Col = T_BorderCol + T_BufferCol, 
    		T_Row = T_BorderRow + T_BufferRow,
    	    MaxRow = MenuHeight + T_Row,
    	    MaxCol = MenuWidth + T_Col,
    		MenuOptionCounter = 0;
    
    	// Change this so that it can dynamically add
    	// Menu items, so not else if, make it based off menu[x]
    	for (int CurrentRow = 0; CurrentRow != MaxRow; ++CurrentRow)
    	{
    		int CurrentCol = 0;
    		while (CurrentCol != MaxCol)
    		{
    			// First we will check for row
    			// Are we in the Border Zone?
    			if (CurrentRow < T_BorderRow/2 
    				|| (CurrentRow >= MaxRow - T_BorderRow/2)
    				&& (CurrentRow > MenuHeight))
    			{
    				cout << "-";
    				++CurrentCol;
    			}			
    			else  // Now we've moved onto columns
    			{
    				// Are we in the Border Zone?
    				if (CurrentCol < T_BorderCol/2
    					|| (CurrentCol >= MaxCol - T_BorderCol/2) 
    					&& (CurrentCol > MenuWidth))
    				{
    					cout << "|";
    					++CurrentCol;
    				}
    				// Brief recursion back to row: Are we in the Buffer Zone?
    				else if ((CurrentRow >= T_BorderRow/2 
    				&& CurrentRow < (T_BufferRow/2) + (T_BorderRow/2)) 
    				|| (CurrentRow >= MaxRow - ((T_BufferRow/2) + (T_BorderRow/2)) 
    				&& CurrentRow < MaxRow - T_BorderRow/2))
    				{
    					cout << " ";
    					++CurrentCol;
    				}
    				// Are we in the Buffer Zone?
    				else if ((CurrentCol >= T_BorderCol/2 
    					&& CurrentCol < (T_BufferCol/2) + (T_BorderCol/2))
    					|| (CurrentCol >= MaxCol - ((T_BufferCol/2) + (T_BorderCol/2)) 
    					&& CurrentCol < MaxCol - T_BorderCol/2))
    				{
    					cout << " ";
    					++CurrentCol;
    				}
    				// Otherwise, we must be at a Menu Option
    				else
    				{
    					sz_t RemainingWidth = (MenuWidth - MenuOption[MenuOptionCounter].size()); //+ ((T_BorderCol/2) + (T_BufferCol/2));
    					if (RemainingWidth > 0)
    					{
    					cout << MenuOption[MenuOptionCounter]
    					<< setfill(' ') << setw(RemainingWidth) << " ";
    					}
    					else 
    					{
    						cout << MenuOption[MenuOptionCounter];
    					}
    					CurrentCol += MenuWidth;
    					++MenuOptionCounter;
    				}
    			}
    		}
    	 cout << endl; // New Row!
    	}
    }
    bool Main_Menu(vector<Student_Record>& student)
    {
    	vector<string> MenuOption;
    	MenuOption.push_back("Add a Student");
    	MenuOption.push_back("List Grades");
    	MenuOption.push_back("Exit");
    
    	AddPrefix(MenuOption);
    
    	sz_t MenuHeight = MenuOption.size(), 
    		 MenuWidth = FindMaxWidth(MenuOption);
    
    	cout << endl << "Main Menu" << endl;
    	WriteMenu(MenuOption, MenuWidth, MenuHeight, 1, 1, 1, 1);
    	int Command = GetIntInput("> ", "\nCommand unreadable: Please try a number from 1-3\n", 1, 3);
    
    	return Do_Main(Command, student);
    }
    
    bool AddStudent_Menu(vector<Student_Record>& student)
    {
    	vector<string> MenuOption;
    	MenuOption.push_back("Add/Change Name");
    	MenuOption.push_back("Add/Change Final");
    	MenuOption.push_back("Add/Change Midterm");
    	MenuOption.push_back("Add/Change Homework");
    	MenuOption.push_back("Add/Change Tests");
    	MenuOption.push_back("Add/Change Quizzes");
    	MenuOption.push_back("Add/Change Projects");
    	MenuOption.push_back("Back to Main Menu");
    
    	AddPrefix(MenuOption);
    
    	sz_t MenuHeight = MenuOption.size(), 
    		 MenuWidth = FindMaxWidth(MenuOption);
    
    	cout << endl << "Add a Student" << endl;
    	WriteMenu(MenuOption, MenuWidth, MenuHeight, 1, 1, 1, 1);
    	int Command = GetIntInput("> ", "\nCommand unreadable: Please try a number from 1-8\n", 1, 8);
    
    	return Do_AddStudent(student, Command);
    }
    Student_Record.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include "Student_Record.h"
    #include "graderIO.h"
    #include "Menu.h"
    
    using namespace std;
    
    bool Compare(const Student_Record& x, const Student_Record& y)
    {
    	return x.name < y.name;
    }
    
    bool Do_AddStudent(vector<Student_Record>& student, int Command)
    {
    	enum Menu_Options
    	{
    		NAME, MIDTERM, FINAL, HOMEWORK, TESTS, QUIZZES,
    		PROJECTS, EXIT
    	};
    
    	--Command;
    
    	switch (Command)
    	{
    		case NAME:
    			cout << endl << "getline(cin, student.name);"
    				 << endl;
    			return true;
    			//break;
    		case MIDTERM:
    			cout << endl << "student.midterm = GetIntInput()" 
    				 << endl;
    			return true;
    			//break;
    		case FINAL:
    			cout << endl << "student.final = GetIntInput()"
    				 << endl;
    			return true;
    			//break;
    		case HOMEWORK:
    			cout << endl << "Add-Edit_Homework();"
    				<< endl;
    			return true;
    			//break;
    		case TESTS:
    			cout << endl << "Add-Edit_Tests();"
    				 << endl;
    			return true;
    			//break;
    		case QUIZZES:
    			cout << endl << "Add-Edit_Quizzes();"
    				 << endl;
    			return true;
    			//break;
    		case PROJECTS:
    			cout << endl << "Add-Edit_Projects();"
    				 << endl;
    			return true;
    			//break;
    		case EXIT:
    			return false;
    			//break;
    		}
    }
    graderIO.h
    Code:
    #ifndef GUARD_graderIO_h
    #define GUARD_graderIO_h
    
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include "Student_Record.h"
    
    bool ParseInt(const std::string&, double&);
    double GetIntInput( const std::string&, std::string, double, double);
    bool Do_Main(int&, std::vector<Student_Record>&);
    
    #endif //GUARD_graderIO_h
    Menu.h
    Code:
    #ifndef GUARD_Menu_h
    #define GUARD_Menu_h
    
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <iomanip>
    #include "Student_Record.h"
    
    void AddPrefix(std::vector<std::string>&);
    std::string::size_type FindMaxWidth(const std::vector<std::string>&);
    void WriteMenu(std::vector<std::string>&, 
    			   std::string::size_type, std::string::size_type, 
    			   std::string::size_type, std::string::size_type, 
    			   std::string::size_type, std::string::size_type);
    bool Main_Menu(std::vector<Student_Record>&);
    bool AddStudent_Menu(std::vector<Student_Record>&);
    
    #endif //GUARD_Menu_h
    Student_Record.h
    Code:
    #ifndef GUARD_Student_Record_h
    #define GUARD_Student_Record_h
    
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    
    struct Student_Record
    {
    	std::string name;
    	double midterm, final;
    	std::vector<double> homework, tests, quizzes, projects;
    };
    
    bool Compare(const Student_Record&, const Student_Record&);
    bool Do_AddStudent(std::vector<Student_Record>&, int);
    
    #endif //GUARD_Student_Record_h
    I figured that the functions in the while statements would return true until they hit exit (and then thusly log out), meaning that they loop. The problem is that they don't do that and if I type 8 to Back out of the AddStudent Menu, it exits the whole program...

  2. #2
    Join Date
    Oct 2002
    Location
    Austria
    Posts
    1,284

    Re: Program Loops going wrong?

    Code:
    	while(Main_Menu(student))
    
    	return 0;
    this will only run once.
    Guess you want to have an empty body of the while loop

    e.g.
    Code:
    	while(Main_Menu(student));  // <<- semicolon
    Kurt

  3. #3
    Join Date
    Mar 2009
    Location
    Granada, Spain
    Posts
    40

    Re: Program Loops going wrong?

    Remember that if you dont use { and } in if, else, for and while it will take the next line like if it were into the {}, so your program works perfect: while showing the menu, return 0.

    PD. "Perfect" in the c++ way, you know.
    Last edited by Tronfi; March 11th, 2009 at 05:04 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured