• 9
• 13
• 9
• 18
• 19

# Local function error

This topic is 4784 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm trying to do an exercise from the book I’m reading. It involves writing a function to get the player's guess and see if it's the secret word or not. I can't seem to get my function to work properly though. I've tried several ways but none have worked. :( Here's the error I get: error C2601: 'playersGuess' : local function definitions are illegal
// Hangman
// The classic game of hangman

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
#include <cctype>

using namespace std;

char playersGuess(char guess);

int main()
{
const int MAX_WRONG = 8;	// maximum number of incorrect guesses allowed

vector<string> words;	// collection of possile words to guess
words.push_back("GUESS");
words.push_back("HANGMAN");
words.push_back("DIFFICULT");

srand(time(0));
random_shuffle(words.begin(), words.end());
const string THE_WORD = words[0];	// word to guess
int wrong = 0;	// number of incorrect guesses
string soFar(THE_WORD.size(), '-');	// word guessed so far
string used = "";	// letters already guessed

cout << "Welcome to Hangman, Good luck!\n";

// main loop
while ((wrong < MAX_WRONG) && (soFar != THE_WORD))
{
cout << "\n\nYou have " << (MAX_WRONG - wrong) << " incorrect guesses left.\n";
cout << "\nYou have used the following letters:\n" << used << endl;
cout << "So far, the word is:\n" << soFar << endl;

char guess;
used +=guess;

if (THE_WORD.find(guess) != string::npos)
{
cout << "That's right! " << guess << " is in the word.\n";

// update soFar to include newly guessed letter
for (int i = 0; i < THE_WORD.length(); ++i)
{
if (THE_WORD == guess)
{
soFar = guess;
}
else
{
cout << "Sorry, " << guess << " isn't in the word.\n";
++wrong;
}
}

// shut down
if (wrong == MAX_WRONG)
cout << "\nYou have been hanged!";
else
cout << "\nYou guessed it!";

cout << "\nThe word was " << THE_WORD << endl;

cin.get();
return 0;
}

char playersGuess(char guess)
{
cout << "\n\nEnter your guess: ";
cin >> guess;
cin.ignore();
guess = toupper(guess);	// make uppercase since secret word is in uppercase
while (used.find(guess) != string::npos)
{
cout << "\nYou've already guessed " << guess << endl;
cout << "Enter your guess: ";
cin >> guess;
cin.ignore();
guess = toupper(guess);
}

return(guess);
}



##### Share on other sites
I commented what I changed
// Hangman// The classic game of hangman#include <iostream>#include <string>#include <vector>#include <algorithm>#include <ctime>#include <cctype>using namespace std;string used = "";//made this globalchar playersGuess(char guess);int main(){	const int MAX_WRONG = 8;	// maximum number of incorrect guesses allowed	vector<string> words;	// collection of possile words to guess	words.push_back("GUESS");	words.push_back("HANGMAN");	words.push_back("DIFFICULT");	srand(time(0));	random_shuffle(words.begin(), words.end());	const string THE_WORD = words[0];	// word to guess	int wrong = 0;	// number of incorrect guesses	string soFar(THE_WORD.size(), '-');	// word guessed so far		// letters already guessed	cout << "Welcome to Hangman, Good luck!\n";	// main loop	while ((wrong < MAX_WRONG) && (soFar != THE_WORD))	{		cout << "\n\nYou have " << (MAX_WRONG - wrong) << " incorrect guesses left.\n";		cout << "\nYou have used the following letters:\n" << used << endl;		cout << "So far, the word is:\n" << soFar << endl;				char guess;		used +=guess;		if (THE_WORD.find(guess) != string::npos)		{			cout << "That's right! " << guess << " is in the word.\n";			// update soFar to include newly guessed letter			for (int i = 0; i < THE_WORD.length(); ++i)			{				if (THE_WORD == guess)				{					soFar = guess;		}		else		{			cout << "Sorry, " << guess << " isn't in the word.\n";			++wrong;		}	}	// shut down	if (wrong == MAX_WRONG)		cout << "\nYou have been hanged!";	else		cout << "\nYou guessed it!";	cout << "\nThe word was " << THE_WORD << endl;	cin.get();	return 0;}}}//added thischar playersGuess(char guess){		cout << "\n\nEnter your guess: ";		cin >> guess;		cin.ignore();		guess = toupper(guess);	// make uppercase since secret word is in uppercase		while (used.find(guess) != string::npos)		{			cout << "\nYou've already guessed " << guess << endl;			cout << "Enter your guess: ";			cin >> guess;			cin.ignore();			guess = toupper(guess);		}				return guess;}

##### Share on other sites
You're missing a closing curly brace somwhere in main() (I haven't checked where exactly yet, I'll update this post when I do), so the compiler thinks you are defining the playerGuess() function within the main() function. And local functions are illegal in C++.

edit:

        if (THE_WORD.find(guess) != string::npos)        {            cout << "That's right! " << guess << " is in the word.\n";            // update soFar to include newly guessed letter            for (int i = 0; i < THE_WORD.length(); ++i)            {                if (THE_WORD == guess)                {                    soFar = guess;                // <-------------- MISSING CURLY HERE?           // <------------------- AND HERE?        }

Looks like the problem is right there: two missing curlies.

##### Share on other sites
You didn't close your "for" bracket
// update soFar to include newly guessed letter
for (int i = 0; i < THE_WORD.length(); ++i)
{

So, with } missing, the compiler see the definition of playersGuess as been within int main(), and thus tell you that this is illegal.

edit: Damn, you guys are too fast.
I might add that, despite the fact that hothead's solution will make your code compile, it will probably not act as you wanted it to, but Fruny correctly showed where you should add a closing bracket.

##### Share on other sites
It's always the small things!

Thanks for the help guys. This presented another problem though. It keeps saying 'used' is not defined.

But it is defined:
string used = ""; // letters already guessed

Is it because the function prototype is before the definition of 'used'?
I know that's a stupid question probably...

##### Share on other sites
"used" is declared within main() scope, thus it will only be accessible within main(). Declare the variable globally if you want to be able to access it from a different scope (The scope of the function playersGuess in this case).

Or you could also pass the variable "used" as a parameter to playersGuess.. It depends on what you think would suit the best for this situation.

Here is a good lesson on scopes if you are interested:

##### Share on other sites
Yep. You presumably want to pass 'used' to playersGuess(), since you're making use of it there. (Passing 'guess' isn't really any good; you don't read from that input variable there, so all that accomplishes is making such a variable available in that function. It should have its own 'guess' instead.) Oh, and you might also want to, you know, call playersGuess() :)

Fixing that, putting in the missing curlies, and fixing up a couple other stylistic things, yields:

// Hangman// The classic game of hangman#include <iostream>#include <string>#include <vector>#include <algorithm>#include <ctime>#include <cctype>using namespace std;char playersGuess(string& used);// I'm giving it the same name in the function as it has in main(). You don't// need to do that, of course, but it's as good of a name as that string is// ever likely to have :s// There is nothing wrong with your indentation style, but I am changing it to// mine anyway. ;Pint main() {  const int MAX_WRONG = 8; // maximum number of incorrect guesses allowed  vector<string> words;	// collection of possile words to guess  // Later we will want to read these in from a file.  words.push_back("GUESS");  words.push_back("HANGMAN");  words.push_back("DIFFICULT");  srand(time(0));  // This is ok, but so far we're shuffling the entire array when we're only  // going to want to select one word; that's a bit wasteful... (silly concern  // with 3 elements though ;) )  random_shuffle(words.begin(), words.end());  // If you feel the need to comment variable declarations with the variable  // purposes, you're either a bit too insecure about the whole thing, or you  // should reconsider the names :)  const string wordToGuess = words[0];  int remainingGuesses = MAX_WRONG; // simplified the logic a bit ;)  string wordAsDisplayed(wordToGuess.size(), '-');  string used = ""; // letters already guessed  cout << "Welcome to Hangman, Good luck!\n";  // main loop  while ((remainingGuesses > 0) && (wordAsDisplayed != wordToGuess))  {    cout << "\n\nYou have " << remainingGuesses << " incorrect guesses left.\n"         << "\nYou have used the following letters:\n" << used         << "\nSo far, the word is:\n" << soFar << endl;		    char guess = playersGuess(used);    // You don't really need a .find() here; since you're writing code to    // iterate manually already, you could add checking logic to the loop    // instead. That's really just an optimization though.    if (wordToGuess.find(guess) != string::npos) {      cout << "That's right! " << guess << " is in the word.\n";      // update display to indicate where the guess appears in the word.      for (int i = 0; i < wordToGuess.length(); ++i) {        if (wordToGuess == guess) {          wordAsDisplayed = guess;        }      }    } else {      cout << "Sorry, " << guess << " isn't in the word.\n";      --remainingGuesses;    }  }  // It's a bit silly to output the word if it was guessed :)  if (remainingGuesses == 0) {    cout << "\nYou have been hanged!\nThe word was " << wordToGuess << endl;  } else {    cout << "\nYou guessed it!" << endl;  }  // I would leave these out, but it's quite debatable if that's a good idea  cin.get();  return 0;}char playersGuess(string& used) {  char guess = 'a';   // We use a do-while loop to avoid repetition. However, we need to make sure  // that we don't write "You've already guessed" the first time through.  // Structuring this to avoid the duplication is often tricky, but I've found  // a clever way here: initialize to a *lowercase* letter, since that can't be  // input.  do {    // TODO: add checking for non-letter characters.    if (guess != 'a') cout << "\nYou've already guessed " << guess << endl;    cout << "\nEnter your guess: " << flush;          // "flush" to make sure it appears before we ask for input.    cin >> guess;    cin.ignore();    guess = toupper(guess);  } while (used.find(guess) != string::npos);  // Since valid guesses always get added to the 'used' string, I'm going to  // add it here. Technically we don't need a return value; main() could just  // look at the end of the used vector - but I guess an explicit return is  // clearer.  used += guess;  return guess;}