Hangman game with hard-coded word or phrase I feel that this implementation can still be simplified.  I've tried to keep variable scopes low and have used as much of the standard library as I could.

It currently works with a hard-coded word or phrase, but I eventually plan on having it work with random words or phrases from a file.

My main concern is in regards to my functions.  Am I using too few or too many of them?  I still feel that main() is doing a little too much.

Note: I have not tagged this as c++11 because there's no utilization of it here, but I am open to any recommendations from C++11.

#include &lt;iostream&gt;
#include &lt;string&gt;

bool isCorrectGuess(const char guess, std::string const&amp; word)
{
    return (word.find(guess) != std::string::npos);
}

std::string updateWrongGuesses(const char guess, std::string const&amp; word, std::string wrongGuesses)
{
    return wrongGuesses += guess;
}

std::string updateCorrectGuesses(const char guess, std::string const&amp; word, std::string correctGuesses)
{
    for (std::string::size_type i = 0; i != word.size(); ++i)
    {
        if (word[i] == guess)
        {
            correctGuesses[i] = guess;
        }
    }

    return correctGuesses;
}

void displayStatus(const unsigned int triesLeft, std::string const&amp; guessedWord, std::string const&amp; wrongGuesses)
{
    std::cout &lt;&lt; "\n\nRemaining Tries: " &lt;&lt; triesLeft;
    std::cout &lt;&lt; "\nWrong Guesses  : " &lt;&lt; wrongGuesses;
    std::cout &lt;&lt; "\n\n" &lt;&lt; guessedWord &lt;&lt; "\n\n";
}

int main()
{
    const std::string word = "rabbit rabbit";

    std::string guessedWord;

    // set up placeholders for word to be guessed
    for (std::string::size_type i = 0; i != word.size(); ++i)
    {
        guessedWord += (isspace(word[i])) ? ' ' : '*';
    }

    unsigned int triesLeft = 8;
    std::string wrongGuesses;

    displayStatus(triesLeft, guessedWord, wrongGuesses);

    std::string attemptedGuesses;

    while (triesLeft &gt; 0 &amp;&amp; guessedWord != word)
    {
        std::cout &lt;&lt; "\nGuess a letter: ";
        char guess;
        std::cin &gt;&gt; guess;
        guess = tolower(guess);
        attemptedGuesses += guess;

        if (isCorrectGuess(guess, word))
        {
            guessedWord = updateCorrectGuesses(guess, word, guessedWord);
        }
        else
        {
            wrongGuesses = updateWrongGuesses(guess, word, wrongGuesses);
            triesLeft--;
        }

        displayStatus(triesLeft, guessedWord, wrongGuesses);
    }

    if (guessedWord == word)
    {
        std::cout &lt;&lt; "\n\nYou've guessed the word/phrase!\n\n";
    }
    else
    {
        std::cout &lt;&lt; "\n\nYou've been hanged...\n\n";
        std::cout &lt;&lt; "The word/phrase is: " &lt;&lt; word;
    }
}
The first thing that nearly jumps out at me is this:

std::string updateWrongGuesses(const char guess, std::string const&amp; word, std::string wrongGuesses)
{
    return wrongGuesses += guess;
}


It's not at all clear why you pass word to this at all, since it doesn't use or modify it. Worse, it looks like it's actually more work to call the function than to re-implement what (little) the function does. At least to me:

wrongGuesses += guess;


...seems simpler and more readable than:

 wrongGuesses = updateWrongGuesses(guess, word, wrongGuesses); 


I think I probably would use a class (or possibly two) in writing this code. My first attempt would be something on this general order:

#include &lt;iostream&gt;
#include &lt;string&gt;

class hangman{
    static const int max_wrong = 8;
    std::string word;
    std::string display;
    std::string wrong;
public:
    hangman(std::string const &amp;word) : word(word) {
        for (char ch : word)
            display += isspace(ch) ? ' ' : '*';
    }

    void enter_guess(char ch) {
        bool correct = false;

        for (std::string::size_type i = 0; i != word.size(); ++i)
            if (word[i] == ch) {
                display[i] = ch;
                correct = true;
            }   
        if (!correct)
            wrong += ch;
    }

    bool is_over() {
        return wrong.size() == max_wrong || display == word;
    }

    std::string final() {
        return "The word was: " + word + (display == word ? "\nYou win!" : "\nYou lose");
    }

    std::string status() {
        return "\nwrong guesses: " + wrong + "\nCurrent word: " + display;
    }
};

char get_guess() {
    std::cout &lt;&lt; "Please enter your guess: ";
    char ch;
    std::cin &gt;&gt; ch;
    return ch;
}

int main()
{
    hangman game("rabbit rabbit");

    do {
        std::cout &lt;&lt; game.status() &lt;&lt; "\n";
        game.enter_guess(get_guess());
    } while (!game.is_over());
    std::cout &lt;&lt; game.final();
}


As far as how much of your code is in main: I try not to treat main any differently from any other function. IMO, you shouldn't strive for main to be as small, or large, or anything else in particular as possible. Rather, main should be a function just about like any other. It should have accomplish something useful. Like any other function, it should have a clearly defined level of abstraction at which it operates, and (for the most part) it should try to stick to it.

As a natural consequence of being bigger, a bigger program will typically have more layers between main and the lowest levels of manipulation, so in a large program it'll typically have little code beyond creating objects and/or calling functions. I wouldn't consider that a particularly worthy goal in itself though. If it fits well with the size and type of program you're writing great--but there's not necessarily a good reason to force it if it doesn't happen to fit or work out well that way.