Thread: Hangman Game - Rewrite (Segmentation Fault?)

  1. #1
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12

    Question Hangman Game - Rewrite (Segmentation Fault?)

    So, after finding a way better example of how to do this in a C++ format, I sort of converted it into C. The problem is, that when I run the program, I get a segmentation fault error. Trying to debug it using gdb, I think it has something to do with strcpy and strcat in the displayEmpty function, but I don't know why past that. I was wondering if anyone could look over this and comment on what needs to be fixed, code would be very much appreciated as I don't always understand what people are talking about when there's no code to go with it. That said, here's the code:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    void matchWord(char *word, char *correctStr, int *correct, int *incorrect, char inputStr[], int *numberInput);
    char *wordTable(int n);
    void displayEmpty(char *string, int length);
    
    int main(void)
    {
      char *word; 		     //store the word from table
      char *correctString=" ";   //store the correct string
      char UserInput[24];        // store user inputs (avoid duplicate entry)
      char again;       //for user play again
      
      int length;      //length of the word
      int correct;     //number of correct guess
      int incorrect;   //number of incorrect guess
      int numberInput; //number of letters that user guests
      int n;           //random number for the word table
      int i = 0;       //declaration of i for for loop
      
      
      printf("\nAre you ready to play? (y for YES, or n for NO) ");
      scanf("%c", &again);
    
      while(again != 'n')
        {
    
        correct=0;
        incorrect=0;
        numberInput=0;
    
        for(i = 0; i < 24; i++)
          {
    	UserInput[i] = '\0';
          }
        
        srand((unsigned)time(NULL));   //seed random number using current time
        n = rand()% 20;
        
        word = wordTable(n);           //random number
        length = strlen(word);
        displayEmpty(correctString, length);
    
        while(incorrect < 7 && correct < length)
          {
    	matchWord(word, correctString, &correct, &incorrect, UserInput, &numberInput);
    	printf("Letter used: \n%c", *UserInput);
          } //end while
    
        if(incorrect == 7)
          {
    	printf("\nSorry! You missed.");
    	printf("The word was: %c", *word);
          } //end if
        else 
          {
    	printf("\nCongratulations!  You are correct!");
    	printf("The word was: %c", *word);
          } //end else
        
        printf("\nTry again? (y for YES; n for NO) ");
        scanf("%c",&again);
        
        }//end while again
      return 0;
    } //end= main
    
    
    
    /* wordTable: returns a word from the Word Table */
    
    char *wordTable(int n)
    {
      char *table[]={"literature", "scholar", "enormous", "influence", "publication", "pioneer", "reshape", "catalyst", "leader", "member", "final", "phonograph", "executed", 
    		 "oldest", "people", "requiring", "screwdriver", "buckshot", "different", "striking"};
    
      return table[n];
    } // end= wordTable
    
    
    
    /* displayEmpty */
    
    void displayEmpty(char *string, int length)
    {
      int i;
      char *ch = "-", *eos = "";
    
      strcpy(string,eos); 
     
      printf("\n");
    
      for(i = 0; i < length; i++)
        {
        strcat(string, ch);
        printf("%c", *ch);
        }
    
      printf("\n");
    } //end displayEmpty word
    
    
    /* MatchWord */
    
    void matchWord(char *word, char *correctStr, int *correct, int *incorrect, char inputStr[], int *numberInput)
    {
      char *temp, *temp2, *temp3, input;
      int correctFlag = *correct;
      int n = 0;
      
      printf("\nWhat letter do you guess?  ");
      scanf("%c", &input);
    
      temp3 = inputStr;
    
      while(*temp3 != '\0')
        {
          if(input == *temp3)
    	{
    	  printf("This letter is already chosen.");
    	  printf("%c",*correctStr);
    	  return;
    	} //end if
          temp3++;
        }
    
      inputStr[(*numberInput)++] = input;
      
      temp = word;
      temp2=correctStr;
    
      while(*temp != '\0')
        {
    
          if(input == *temp)
          {
    	*temp2 = input;
    	(*correct)++;
    	n++;
    	temp++;
    	temp2++;
          }
        
          else
    	{
    	  temp++; 
    	  temp2++;
    	}
      }//end while
      
      printf("\n");
      printf("%c", *correctStr);
      if(*correct == correctFlag)
        {
        (*incorrect)++;
        }
     
    }// end matchWord
    Last edited by tigrfire; 11-29-2005 at 04:19 PM.
    --
    growl.

  2. #2
    Dump Truck Internet valis's Avatar
    Join Date
    Jul 2005
    Posts
    357
    you are passing a string literal (*correctString) to strcpy and strcat, allocate some space in the heap or make it an array, and that should fix your problem.
    Code:
    char *correctString = malloc(255);

  3. #3
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12
    I tried to use your idea using the malloc(255) definition of *correctString since I don't know how to do it with an array (I tried something and it didn't work out ver well :P )

    Anyways, now my program executes, but something is still wrong with it, here is some sample output:
    Code:
    Are you ready to play? (y for YES, or n for NO) y
    
    --------
    
    What letter do you guess?  
    -Letter used: 
    
    
    What letter do you guess?  f
    
    -Letter used: 
    
    
    What letter do you guess?  This letter is already chosen.-Letter used: 
    
    
    What letter do you guess?  a
    .
    .
    .
    What letter do you guess?  This letter is already chosen.-Letter used: 
    
    
    What letter do you guess?  j
    
    -Letter used: 
    
    
    Sorry! You missed.The word was: c
    Try again? (y for YES; n for NO)
    So, now the problem is that (among other things) it's not reading the word correctly from the wordTable function. I don't know why this is, it only manages to get the first letter of it.

    In addition, it thinks all the letters you input have already been chosen, any idea as to why it behaves like this?
    --
    growl.

  4. #4
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12
    I was able to get rid of the recurring letter already chosen, it was a pretty simple mistake. I replaced my scanf with getchar and a while statement so it would read the letter and not the return, here's the code again:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    void matchWord(char *word, char *correctStr, int *correct, int *incorrect, char inputStr[], int *numberInput);
    char *wordTable(int n);
    void displayEmpty(char *string, int length);
    
    int main(void)
    {
      char *word; 		               //store the word from table
      char *correctString= malloc(255);    //store the correct string
      char UserInput[24];                  //store user inputs (avoid duplicate entry)
      char again;                          //for user play again
      
      int length;      //length of the word
      int correct;     //number of correct guess
      int incorrect;   //number of incorrect guess
      int numberInput; //number of letters that user guests
      int n;           //random number for the word table
      int i = 0;       //declaration of i for for loop
      
      
      printf("\nAre you ready to play? (y for YES, or n for NO) ");
      scanf("%c", &again);
    
      while(again != 'n')
        {
    
        correct=0;
        incorrect=0;
        numberInput=0;
    
        for(i = 0; i < 24; i++)
          {
    	UserInput[i] = '\0';
          } //end for
        
        srand((unsigned)time(NULL));   //seed random number using current time
        n = rand()% 20;
        
        char table[][20]={"literature", "scholar", "enormous", "influence", "publication", "pioneer", "reshape", "catalyst", "leader", "member", "final", "phonograph", "executed", "oldest", "people", "requiring", "screwdriver", "buckshot", "different", "striking"};
    
        word = table[n];
    
        printf("%c", *word);
    
        /*  word = wordTable(n);           //random number */
    
        length = strlen(word);
        displayEmpty(correctString, length);
    
        while(incorrect < 7 && correct < length)
          {
    	matchWord(word, correctString, &correct, &incorrect, UserInput, &numberInput);
    	printf("Letter used: \n%c", *UserInput);
          } //end while
    
        if(incorrect == 7)
          {
    	printf("\nSorry! You missed.");
    	printf("The word was: %c", *word);
          } //end if
        else 
          {
    	printf("\nCongratulations!  You are correct!");
    	printf("The word was: %c", *word);
          } //end else
        
        printf("\nTry again? (y for YES; n for NO) ");
        scanf("%c",&again);
        
        }//end while
      return 0;
    } //end main
    
    
    
    /* wordTable: returns a word from the Word Table */
    /*
    char *wordTable(int n)
    {
      char table[][20]={"literature", "scholar", "enormous", "influence", "publication", "pioneer", "reshape", "catalyst", "leader", "member", "final", "phonograph", "executed", 
    		 "oldest", "people", "requiring", "screwdriver", "buckshot", "different", "striking"};
    
      return table[n];
      } // end wordTable */
    
    
    
    /* displayEmpty */
    
    void displayEmpty(char *string, int length)
    {
      int i;
      char *ch = "-", *eos = "";
    
      strcpy(string,eos); 
     
      printf("\n");
    
      for(i = 0; i < length; i++)
        {
        strcat(string, ch);
        printf("%c", *ch);
        }
    
      printf("\n");
    } //end displayEmpty
    
    
    /* MatchWord */
    
    void matchWord(char *word, char *correctStr, int *correct, int *incorrect, char inputStr[], int *numberInput)
    {
      char *temp, *temp2, *temp3, input;
      int correctFlag = *correct;
      int n = 0;
      
      printf("\nWhat letter do you guess?  ");
      input = getchar();
      while(getchar() != '\n');
    
      /*  scanf("%c", &input);*/
    
      temp3 = inputStr;
    
      while(*temp3 != '\0')
        {
          if(input == *temp3)
    	{
    	  printf("This letter is already chosen.");
    	  printf("%c",*correctStr);
    	  return;
    	} //end if
          temp3++;
        } //end while
    
      inputStr[(*numberInput)++] = input;
      
      temp = word;
      temp2=correctStr;
    
      while(*temp != '\0')
        {
    
          if(input == *temp)
          {
    	*temp2 = input;
    	(*correct)++;
    	n++;
    	temp++;
    	temp2++;
          } //end if
        
          else
    	{
    	  temp++; 
    	  temp2++;
    	} //end else
      }//end while
      
      printf("\n");
      printf("%c", *correctStr);
      if(*correct == correctFlag)
        {
        (*incorrect)++;
        }
     
    }// end matchWord
    Notice that some of the other code has been commented out, such as wordTable. I decided to just stick it in the main function where I had it working in another program. Problem is, that didn't fix the problem of it outputting the word right anyways. I also added a cheat line to tell you what the word is, which it displays as always being a single character.., and even if you guess the character, the program tells you you are incorrect.
    --
    growl.

  5. #5
    Dump Truck Internet valis's Avatar
    Join Date
    Jul 2005
    Posts
    357
    you have mostly %s %c mixup issues, %c only prints a character, to print a string use %s.
    Code:
    printf("\nLetters used: %s\n", UserInput);
    /* not printf("\nLetters used: %c\n", *UserInput); */
    Code:
    printf("\nCongratulations!  You are correct!\n");
    printf("The word was: %s", word);
    /* not printf("The word was: %c", *word); */
    and
    Code:
    printf("%s", correctStr);
    /* not printf("%c", *correctStr); */
    You could also drop all the temp variables (but temp2 which could be given a better name) and replace
    Code:
    while(*temp3 != '\0')
        {
          if(input == *temp3)
    {
      printf("This letter is already chosen.");
      printf("%c",*correctStr);
      return;
    } //end if
          temp3++;
        } //end while
    Code:
    /* with */
    if (strchr(inputStr, input) != NULL)
    {
        printf("This letter is already chosen.");
        return;
    }
    Also your tricking the user with
    Code:
    input = getchar();
    because when they hit enter it doesn't take the first character they see, instead it takes the first character they pressed, even if they go back and delete it.
    Last edited by valis; 11-29-2005 at 08:00 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Re: Segmentation fault
    By turkish_van in forum C Programming
    Replies: 8
    Last Post: 01-20-2007, 05:50 PM
  3. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM
  4. strcat segmentation fault
    By captain-cat in forum C Programming
    Replies: 3
    Last Post: 07-20-2004, 10:29 AM
  5. Segmentation Fault Error
    By jcramer in forum C Programming
    Replies: 2
    Last Post: 11-23-2003, 02:16 PM