Hello all,

Got a small problem I'm trying to figure out an obscure error (to me). What I'm trying to do is implement error handling with a loop count within a while statement for two sets of Menus in my Hangman game. Perhaps you all can lend me hand in discovering where the problem lies?

I understand that each .cpp file has it's own loop declaration and initiation and this is the problem but how would I initiate error handling the way I want to without getting these errors:


Error 1 - error LNK2005: "int loop" (?loop@@3HA) already defined in HangmanMenu.obj
Error 2 - fatal error LNK1169: one or more multiply defined symbols found 1

MainMenu.cpp

#include "MainMenu.h"
#include "HangmanMenu.h"
#include "Controller.h"
#include <iostream>
#include <cctype>
#include <string>

using namespace std;

char selection_new;
int loop = 0;


Menu::Menu()
{
}


void Menu::MenuLoop()
{
	while (selection_new != 'X')   //As long as user does not choose QUIT, run the MenuInput loop
	{
       MenuInput();
	}
}

void Menu::MenuInput()
{
	
	print(); 
	SetInput(); //Again, this function would basically consist of cin >> selection;
	DetermineMenuInput();
}

void Menu::print()
{
	system ("cls");        //Clears the screen before displaying the menu
	cout << endl << endl << endl;
	cout << "                              Main Menu" << endl << endl;
	cout << "                              A - Play" << endl;
	cout << "                              X - Exit\n" << endl << endl;
	cout << "                        Please enter your choice: ";
}

char Menu::SetInput()   //Equates to a cin statement
{
	cin >> selection_new;
	selection_new = toupper(selection_new);
	return selection_new;
}

void Menu::DetermineMenuInput()      //Determine user's menu selection
{
	 while (loop != 1)  //If loop count is not equal to 1, continue looping getSelection function.
	 {
		 
		//Converts to upper case if user enters selectio in lower case
	
		switch (selection_new)   /*Looks through the selections to see which one matches the user input;
								   System ("cls") clears the screen before the new data is displayed
	                               then the Menu is re-displayed*/
		{
			case 'A':
				system ("cls");     
				play();			//Allows the user to play a game - not functional yet
				loop = 1;
				break;
			case 'X':
				system ("cls");   
				cout << endl << endl << endl;
				cout << "                             Thanks for Playing." << endl;
				cout << endl;
				loop = 1;
				break;	
			default:
				cout << "\n\nInvalid selection error." << endl;
				cout <<"\n\nPlease enter your selection: ";
				cin >> selection_new;
				selection_new = toupper(selection_new);
		}
	 }
}

HangmanMenu.cpp (pertinent snippet)

#include "HangmanMenu.h"
#include "LevelFolders.h"
#include "MainMenu.h"
#include "ScoreBoard.h"
#include <iostream>
#include <fstream>


using namespace std;
int loop = 0;

class notNewWord     ////Used for Throw specifier and handler for Catch statement to execute 
{
};

class noWordToDelete   //Used for Throw specifier and handler for Catch statement to execute
{
};

HangmanMenu::HangmanMenu()
{
}

void HangmanMenu::MakeMenuInstance()   //Make an temporary instance of the Hangman sub-menu
{
HangmanMenu Temp;
Temp.HangmanMenu::MenuLoop();
}

void HangmanMenu::MenuLoop()
{
	while (selection_new != 'X')
	{
		SubMenuInput();
	}
}

void HangmanMenu::SubMenuInput()  //Show menu, allow input and determine input for menu
{
	print();
	SetInput();            //Represents the same as a cin statement
	DetermineMenuInput();  //Determine user's menu selection_new
}

void HangmanMenu::print()
{
	//display the Hangman menu
	cout << endl << endl << endl; 
	cout << "                              Hangman Menu Screen" << endl << endl;
	cout << "                              A - Play Hangman" << endl;
	cout << "                              B - Delete a word" << endl;
	cout << "                              C - Add a word" << endl;
	cout << "                              X - Quit to Main Menu" << endl << endl;
	cout << "                              Please enter your choice: ";
}

char HangmanMenu::SetInput()   //Get user input and returns selection
{
	cin >> selection_new;
	selection_new = toupper(selection_new);
	return selection_new;
}

void HangmanMenu::DetermineMenuInput()
{
	 while (loop != 2)  //If loop count is not equal to 1, continue looping getSelection function.
	 {
	
	 /*Below: Looks through the selection_news to see which one matches the input.
	   System ("cls") clears the screen before the new data is displayed
	   then the Menu is re-displayed*/

		switch (selection_new)    //Switch statements for Hangman Menu options
		{
			case 'A':
				system ("cls");
				LevelFolders::LevelFoldersSubMenu();
				loop = 2;
				break;
			case 'B':
				system ("cls");
				DeleteWord();  //checks to see if the word entered is in the words file. If found, removes the word from the file (Both Easy and Hard are checked)
				cout << endl;
				loop = 2;
				break;
			case 'C':
				system ("cls");
				HangmanMenu::AddWord();   //Checks to see if the word is in the file. If not, it adds the word
				cout << endl;
				loop = 2;
				break;
			case 'X':
				system ("cls");
				cout << endl << endl << endl;
				cout << "                      Quitting to Main Menu" << endl << endl;
				system ("cls");
				loop = 2;
				break;
			default:
				system ("cls");
				cout << "Error: Invalid selection!" << endl << endl;
				cout <<"\n\nPlease enter your selection: ";
				cin >> selection_new;
				selection_new = toupper(selection_new);
			
		}
	 }
}

I can post each respective header file, if needed.
Thanks for any advice or direction in advance.

Both files have a variable called "loop" defined within them in the global scope. Those identical declarations are butting heads. I don't see your class definitions for HangmanMenu and MainMenu. Based on the way you are using the "loop" variables I think you would be better off moving them from the global scope to the appropriate class scopes.

Either that, or add the extern keyword to one of them so that there is only one variable called "loop" in existence in the entire program. The only problem with this idea is that all of your loops will depend on the same variable, which I think you may not want.

Another option might be a static global. A static global is defined and used like a global, but only visible within the file it's declared in.

commented: Fbody was direct and to the point and gave me multiple ideas for my solution +1

Both files have a variable called "loop" defined within them in the global scope. Those identical declarations are butting heads. I don't see your class definitions for HangmanMenu and MainMenu. Based on the way you are using the "loop" variables I think you would be better off moving them from the global scope to the appropriate class scopes.

Either that, or add the extern keyword to one of them so that there is only one variable called "loop" in existence in the entire program. The only problem with this idea is that all of your loops will depend on the same variable, which I think you may not want.

Another option might be a static global. A static global is defined and used like a global, but only visible within the file it's declared in.

Thanks Fbody, that did it! I'm still learning and this helped me alot.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.