0

I wrote this code for a hang man game to read in words into a vector from a dictionary file. However the code keeps crashing immediately and I cannot for the life of me see where the cause of it might be. Any advice you can offer would be a great help!

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

const int MAX_TRIES=5;

int letterFill (char guess, string secretword, string &guessword)
{
    int i;
    int matches=0;
    int len=secretword.length();
    for (i = 0; i< len; i++)
    {
    // Did we already match this letter in a previous guess?
    if (guess == guessword[i])
    return 0;

    // Is the guess in the secret word?
        if (guess == secretword[i])
        {
            guessword[i] = guess;
            matches++;
        }
    }
return matches;
}


int main ()
{
    string name;
    char letter;
    int num_of_wrong_guesses=0;

   //Input file
   ifstream inFile;
   inFile.open("dictionary2.txt");

   //Vector with elements preallocated 
   //to increase push_back speed
   vector<string> dict;

    //Temporary string
    string temp;

    //Grab words from file into vector
    while(inFile >> temp)
    {
      dict.push_back( temp );
    }  
    //Close input file
    inFile.close();

    //Seed random number generator
    srand(time(NULL));

    //Generate a random index
    int index = rand() % dict.size();

    //Word to use for hangman
    string hangManWord = dict[index];
    cout << hangManWord << endl;   


    // Initialize the secret word with the * character.
    string unknown(hangManWord.length(),'*');

    // welcome the user
    cout << "\nWelcome to hangman";
    cout << "\nEach letter is represented by an underscore.";
    cout << "\nYou have to type only one letter in one try";
    cout << "\nYou have " << MAX_TRIES << " attempts left";
    cout << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";

    // Loop until the guesses are used up
    while (num_of_wrong_guesses < MAX_TRIES)
    {
        cout << "\n" << unknown;
        cout << "\n Guess a letter: ";
        cin >> letter;
        // Fill secret word with letter if the guess is correct,
        // otherwise increment the number of wrong guesses.
        if (letterFill(letter, hangManWord, unknown)==0)
        {
            cout << endl << "Whoops! That letter isn't in there!" << endl;
            num_of_wrong_guesses++;
        }
        else
        {
            cout << endl << "You found a letter! Isn't that exciting!" << endl;
        }
        // Tell user how many guesses has left.
        cout << "You have " << MAX_TRIES - num_of_wrong_guesses;
        cout << " guesses left." << endl;
        // Check if user guessed the word.
        if (hangManWord==unknown)
        {
            cout << hangManWord << endl;
            cout << "Yeah! You got it!";
            break;
        }
    }
    if(num_of_wrong_guesses == MAX_TRIES)
    {
        cout << "\nSorry, you lose...you've been hanged." << endl;
        cout << "The word was : " << hangManWord << endl;
    }
    cin.ignore();
    cin.get();
    return 0;
}
user3456450
  • 27
  • 1
  • 3
  • 1
    Where is it crashing and what error message(s) are you getting? – ElGavilan Mar 24 '14 at 17:19
  • 1
    Please learn how to use a debugger, instead of posting all of your code here! Narrow down first, where exactly the problem occurs and ask if you don't understand anything particular! – πάντα ῥεῖ Mar 24 '14 at 17:29
  • It's the whole "g.exe has stopped working" message. I have to close the program – user3456450 Mar 24 '14 at 17:35
  • 1
    @user3456450 As mentioned, use a debugger first and step through your program line by line!! If you don't know how to use a debugger, you can always fallback to [_'caveman debugging_'](http://stackoverflow.com/questions/186237/program-only-crashes-as-release-build-how-to-debug)! – πάντα ῥεῖ Mar 24 '14 at 17:45

2 Answers2

3

Since you don't know how to use the debugger, the places in the code that are suspicious are these:

int len=secretword.length();
for (i = 0; i< len; i++)
{
  // Did we already match this letter in a previous guess?
   if (guess == guessword[i])

and this:

 //Generate a random index
int index = rand() % dict.size();

//Word to use for hangman
string hangManWord = dict[index];

For the first item, you use the length of secretword to determine how many iterations to loop (and then use "i" as the loop counter). However, you use "i" in the guessword string. How do you know if position "i" in guessword is out of bounds?

According to how you call that function, the secret word may be "ladder" and the guessword could be "lad". When you get to index 3 of the secret word, there is no guessword[3], causing an erroneous access. So basically you have two separate strings, and you're assuming that they are the same size when they may not be the same size. You fix this by making sure that the loop goes from

[ 0, min(guessword.size(), secretword.size()) ).

In other words, the loop should only loop starting from 0 to the smaller in length of the two strings, less one.

For the second item, the value of index may or may not be in bounds of the dict vector. Please check this by printing out the values of index and dict.size(). If index is out of bounds of the dict.size(), then you know what the problem is -- your dictionary either didn't read all the words you thought it did, or the index calculation is wrong.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Thank you so much for this, and the Codeblocks! You've actually been more help than my lecturer has in 3 weeks! – user3456450 Mar 25 '14 at 18:18
2

You have an integer division by zero on line

//Generate a random index
int index = rand() % dict.size();

You can fix this by simply first checking if dict.size() is > 0 and only if it is, you do that division. If it is not, you don't need an index anyway, because there are no elements inside your dict.

  • I tried that and it's still instantly crashing. Also I know that there is words in dict because I have the file open as well separately... – user3456450 Mar 24 '14 at 17:34
  • 2
    Why not, as others suggested, use the debugger? Then things will not "instantly crash" -- instead you will step a line at a time and see exactly which line caused the issue. If not that, why don't you output what the value of index and dict.size() before you use them, so that you know what you're dealing with? – PaulMcKenzie Mar 24 '14 at 17:37
  • I've just started studying c++ in the last 3 weeks and the lecturer hasn't mentioned any debugger and looking online, I cannot find any either. If you could recommend on that would be great though – user3456450 Mar 24 '14 at 17:40
  • 1
    @user3456450: So you were just taught to write programs and then cross your fingers hoping the program works? You weren't taught to, at the very least, print out variables to see what they are so that you can narrow down problems? – PaulMcKenzie Mar 24 '14 at 17:42
  • Well I did hard code it and it worked fine, it's only since I've started file inputting (which he hasn't covered in the lectures) that this has been happening. And we've just been using notepad++ to write the programes and mingw to run them – user3456450 Mar 24 '14 at 17:44
  • 1
    Then you need to get an IDE (for example, CodeBlocks), or learn to use gdb to debug your programs. – PaulMcKenzie Mar 24 '14 at 17:46