int loc = target.find(letter);

            if (loc == string::npos)

            {

                cout << "Oh, bad guess!\n";

                --guesses;

                badchars += letter; // add to string

            }

            else

            {

                cout << "Good guess!\n";

                attempt[loc]=letter;

                // check if letter appears again

                loc = target.find(letter, loc + 1);

                while (loc != string::npos)

                {

                    attempt[loc]=letter;

                    loc = target.find(letter, loc + 1);

                }

           }

            cout << "Your word: " << attempt << endl;

            if (attempt != target)

            {

                if (badchars.length() > 0)

                    cout << "Bad choices: " << badchars << endl;

                cout << guesses << " bad guesses left\n";

            }

        }

        if (guesses > 0)

            cout << "That's right!\n";

        else

            cout << "Sorry, the word is " << target << ".\n";

        cout << "Will you play another? ";

        cin >> play;

        play = tolower(play);

    }

    cout << "Bye\n";

    return 0;

}

Here’s a sample run of the program in Listing 16.3:

Will you play a word game? y

Guess my secret word. It has 6 letters, and you guess

one letter at a time. You get 6 wrong guesses.

Your word: ------

Guess a letter: e

Oh, bad guess!

Your word: ------

Bad choices: e

5 bad guesses left

Guess a letter: a

Good guess!

Your word: a--a--

Bad choices: e

5 bad guesses left

Guess a letter: t

Oh, bad guess!

Your word: a--a--

Bad choices: et

4 bad guesses left

Guess a letter: r

Good guess!

Your word: a--ar-

Bad choices: et

4 bad guesses left

Guess a letter: y

Good guess!

Your word: a--ary

Bad choices: et

4 bad guesses left

Guess a letter: i

Good guess!

Your word: a-iary

Bad choices: et

4 bad guesses left

Guess a letter: p

Good guess!

Your word: apiary

That's right!

Will you play another? n

Bye

Program Notes

In Listing 16.3, the fact that the relational operators are overloaded lets you treat strings in the same fashion you would treat numeric variables:

while (guesses > 0 && attempt != target)

This is easier to follow than, say, using strcmp() with C-style strings.

The program uses find() to check whether a character was selected earlier; if it was already selected, it will be found in either the badchars string (bad guesses) or in the attempt string (good guesses):

if (badchars.find(letter) != string::npos

    || attempt.find(letter) != string::npos)

The npos variable is a static member of the string class. Its value, recall, is the maximum allowable number of characters for a string object. Therefore, because indexing begins at zero, it is one greater than the largest possible index and can be used to indicate failure to find a character or a string.

The program makes use of the fact that one of the overloaded versions of the += operator lets you append individual characters to a string:

badchars += letter;  // append a char to a string object

The heart of the program begins by checking whether the chosen letter is in the mystery word:

int loc = target.find(letter);

If loc is a valid value, the letter can be placed in the corresponding location in the answer string:

attempt[loc]=letter;

However, a given letter might occur more than once in the mystery word, so the program has to keep checking. The program uses the optional second argument to find(), which specifies a starting place in the string from which to begin the search. Because the letter was found at location loc, the next search should begin at loc + 1. A while loop keeps the search going until no more occurrences of that character are found. Note that find() indicates failure if loc is after the end of the string:

// check if letter appears again

loc = target.find(letter, loc + 1);

while (loc != string::npos)

{

    attempt[loc]=letter;

    loc = target.find(letter, loc + 1);

}

What Else Does the string Class Offer?

The string library supplies many other facilities. There are functions for erasing part or all of a string, for replacing part or all of one string with part or all of another string, for inserting material into a string or removing material from a string, for comparing part or all of one string with part or all of another string, and for extracting a substring from a string. There’s a function for copying part of one string to another string, and there’s a function for swapping the contents of two strings. Most of these functions are overloaded so that they can work with C-style strings as well as with string objects. Appendix F describes the string library function briefly, but let’s talk about a few more features here.

Перейти на страницу:

Все книги серии Developer's Library

Похожие книги