Thread: Hangman program randomly outputs question marks at the end of output

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    7

    Hangman program randomly outputs question marks at the end of output

    So basically, I'm doing a hangman C++ program as a class assignment. But the problem is, three of the words (wyvern, scythe, and duckboards) all output question marks at the end of their outputs, making them impossible to guess. Here's my code:

    NOTE: I know that it's really inefficient. Please don't tell me that.

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <time.h>
    
    using namespace std;
    
    int Lettercheck(char achar) // Checks to see if a letter has been guessed
    {
         switch(achar)
            {
                                 case 'A':
                                 case 'a': 
                                      return 0;
                                      break;
                                 case 'B':
                                 case 'b':
                                      return 1;
                                      break;
                                 case 'C':
                                 case 'c': 
                                      return 2;
                                      break;
                                 case 'D':
                                 case 'd':
                                      return 3;
                                      break;
                                 case 'E':
                                 case 'e': 
                                      return 4;
                                      break;
                                 case 'F':
                                 case 'f':
                                      return 5;
                                      break;
                                 case 'G':
                                 case 'g': 
                                      return 6;
                                      break;
                                 case 'H':
                                 case 'h':
                                      return 7;
                                      break;
                                 case 'I':
                                 case 'i': 
                                      return 8;
                                      break;
                                 case 'J':
                                 case 'j':
                                      return 9;
                                      break;
                                 case 'K':
                                 case 'k': 
                                      return 10;
                                      break;
                                 case 'L':
                                 case 'l':
                                      return 11;
                                      break;
                                 case 'M':
                                 case 'm': 
                                      return 12;
                                      break;
                                 case 'N':
                                 case 'n':
                                      return 13;
                                      break;
                                 case 'O':
                                 case 'o': 
                                      return 14;
                                      break;
                                 case 'P':
                                 case 'p':
                                      return 15;
                                      break;
                                 case 'Q':
                                 case 'q':
                                      return 16;
                                      break;
                                 case 'R':
                                 case 'r':
                                      return 17;
                                      break;
                                 case 'S':
                                 case 's':
                                      return 18;
                                      break;
                                 case 'T':
                                 case 't':
                                      return 19;
                                      break;
                                 case 'U':
                                 case 'u':
                                      return 20;
                                      break;
                                 case 'V':
                                 case 'v':
                                      return 21;
                                      break;
                                 case 'W':
                                 case 'w':
                                      return 22;
                                      break;
                                 case 'X':
                                 case 'x':
                                      return 23;
                                      break;
                                 case 'Y':
                                 case 'y':
                                      return 24;
                                      break;
                                 case 'Z':
                                 case 'z':
                                      return 25;
                                      break;
                                      
                                 default:
                                      break;
            }
    }
    
    
    int main(int argc, char *argv[])
    {
        srand(unsigned(time(NULL)));
        char *words[10] = {"glyph", "pyrrhic", "pygmy", "scythe", "onomatopoeia", "wyvern", "proxy", "zymurgy", "Kalamazoo", "duckboards"};
        char *word;
        char letter;
        char theword[256];
        char guess[256];
        char displayword[256];
        int x;
        int wordlen;
        int flag = 0;
        int lettercheck=0;
        int letters[26];
        x = rand() % 10; // Chooses a word
        word = words[x];
        wordlen = strlen(word); // Gets the length of the word
        theword[0] = '\0'; // initializes the array
        strcat (theword, word); // converts char * to char
        for (int wordlencounter = 0; wordlencounter < wordlen; wordlencounter++)
        {
            displayword[wordlencounter] = '-';
        }
        int whilea = 0;
        for (int anothercounter = 0; anothercounter < 26; anothercounter++)
        {
            letters[anothercounter] = 0;
        }
        cout << "The word is: " << displayword << endl;
        while (whilea < 6)
        {
              while(lettercheck != 1)
              {
                                cout << "Guess a letter.\n";
                                cin >> letter;
                                if (letters[Lettercheck(letter)] == 1) cout << "You've already guessed that letter!" << endl;
                                else
                                {
                                    letters[Lettercheck(letter)] = 1;
                                    break;
                                }
              }
              for (int counter = 0; counter < wordlen; counter++)
              {
                  if (letter == theword[counter])
                  {
                            displayword[counter] = theword[counter];
                            flag++;
                  }
              }
              if (flag == 0) whilea++;    
              flag = 0;
              if (strcmp(displayword, theword) == 0)
              {
                                      cout << "You won!\n";
                                      break;
              }
              cout << "The word is: " << displayword << endl;
              
                      
        }        
        if (whilea == 6) cout << "Sorry, you lost.\n";
        system("PAUSE");
        
    return EXIT_SUCCESS;
    }
    Thanks for any help in advance.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I'd say your biggest problem is: "converts char * to char".

    Also, automatic variables of standard types may have random values.

    In other words, you do have a major problem, but it isn't the problem you think you have; the problem you think you have is just the way it has manifested in one test.

    Soma

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    7
    At first, I had no idea what you meant. It just clicked. For anyone else's reference, the problem was solved by adding this line of code:

    Code:
    strcat (theword, word); // converts char * to char
    for (int wordlencounter = 0; wordlencounter < wordlen; wordlencounter++)
        {
            displayword[wordlencounter] = '-';
        }
    displayword[wordlen] = '\0'; // This line right here
    int whilea = 0;
    Thanks for the help!

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    ^_^

    Congratulations.

    I'm also extremely pleased with you. Behavior like this, returning to specifically state how you solved your problem, will get you a lot of respect on a programming forum.

    Soma

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Like Soma, I congratulate you on both finding a solution, and on returning to tell us what you did.

    Some minor comments to improve your code:
    The function called LetterCheck() has a comment saying that it checks if the letter has been guessed or not. That's not quite what the actual function does (it helps in such a process, but it's not what it does).

    Second, it is about 90 lines too long:
    Code:
    int Lettercheck(char achar) // Checks to see if a letter has been guessed
    {
        if (isalpha(achar))
           return toupper(achar)-'A';
        else
           return -1;
    }
    Note that you then need to check if the return value is -1, and do something meaningful (like saying "That's not a letter at all"). Your current function returns garbage in the case of "not a letter", and it may or may not be within the range of 0..25.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Posts
    7
    Quote Originally Posted by matsp View Post
    Second, it is about 90 lines too long:
    Code:
    int Lettercheck(char achar) // Checks to see if a letter has been guessed
    {
        if (isalpha(achar))
           return toupper(achar)-'A';
        else
           return -1;
    }
    Note that you then need to check if the return value is -1, and do something meaningful (like saying "That's not a letter at all"). Your current function returns garbage in the case of "not a letter", and it may or may not be within the range of 0..25.

    --
    Mats
    I believe what your code does, if my knowledge doesn't fail me, is it checks to see if the character is a letter. If so, returns the upper letter character's ASCII value minus the ASCII code value of A, which is 65. This would return 0 for A, 1 for B, etc.

    Then, if it is not a character, it would return a value of -1 to show that it is not a letter, acting as an error trap. It would be of type int in order to return an actual number and not a character.

    Is that correct?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem building Quake source
    By Silvercord in forum Game Programming
    Replies: 16
    Last Post: 07-11-2010, 09:13 AM
  2. Client-server system with input from separate program
    By robot-ic in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-16-2009, 03:30 PM
  3. sorting output on student info program
    By indigo0086 in forum C++ Programming
    Replies: 2
    Last Post: 11-05-2002, 11:29 AM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. Replies: 2
    Last Post: 05-10-2002, 04:16 PM