Thread: Variable suddenly changes value during runtime and I don't know why

  1. #1
    Registered User
    Join Date
    Jun 2016
    Posts
    4

    Unhappy Variable suddenly changes value during runtime and I don't know why

    In my code for a hangman game below, the lives variable suddenly changes its value from 5 to 0 during runtime:
    Code:
    You have 5 lives.
    -------
    Put in a letter.
    p
    You guessed right.
    You have 0 lives.
    p------
    Put in a letter.
    Below is my code:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) {
    
    char *word;
    
    
    int i = rand() % 2;
    printf("%d", i);
    
    switch(i) {
    
    case 0:
    word = "string";
    break;
    
    case 1:
    word = "program";
    break;
    
    }
    
    char *placeholder = word;
    int length = strlen(word);
    char *temp = malloc( length * sizeof(char) );
    bool finished = false;
    int j;
    int lives = 5;
    
    
    for(j=0; j<(length); j++) {
    
    temp[j] = '-';
    
    }
    
    lives = 5;
    while(finished == false) {
        
        printf("You have %d lives.\n", lives);
        printf("%s\n", temp);
        printf("Put in a letter.\n");
        char letter;
        char *stringletter = malloc(sizeof(char));
        scanf("%s", &letter);
        *stringletter = letter;
    
        if( (strrchr(word, letter) != NULL) && (strrchr(temp,letter) == NULL) ) {
    
    
            int index = strcspn(word, stringletter);
            printf("You guessed right.\n");
            temp[index] = letter;
    
            for(j=0; j<length; j++) {
    
                if(word[j] == letter)
                    temp[j] = word[j];
    
            }
            
            
    
        } else if(strrchr(word, letter) == NULL) {
    
            printf("You guessed wrong. You lose a life\n");
            --lives;
    
        } else {
    
            printf("You already have that letter. Try again.\n");
    
        }
    
        if(strcmp(word, temp) == 0) {
    
            printf("You win! You guessed the word correctly. It's %s\n", word);
            break;
    }
        if(lives < 0) {
            printf("You're out of lives. You lose.\n");
            break;
        
    
        }
    
    
    
    }
    
    return 0;
    
    }
    I am unsure why this is happening. Could someone help me find out why?

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Storing your strings and answers in character arrays would help, especially if you are going to use functions like strrchr() and strcmp() to do this.

    You seem to be very confused on strings so just allocate a small array for answers and take the first character like this
    Code:
    char answers[1000];
    printf("Put in a letter.\n");
    scanf("%s", answers); /* now there is room for a sequence of bytes, plus '\0', required by strcmp, strrchr, etc */
    char letter = answers[0];
    Now you have answers as "p" for your string functions.

  3. #3
    Registered User
    Join Date
    Jun 2016
    Posts
    4
    But how does that stop the lives variable from changing?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    In two places, you have short allocated strings which have no \0 termination.

    Code:
        char *stringletter = malloc(sizeof(char));
        scanf("%s", &letter);
        *stringletter = letter;
    strcspn (used later) needs stringletter to have a \0.
    Otherwise, it might match garbage and give you a duff index to write to.

    Code:
        printf("%s\n", temp);
    Again, temp has no \0.

    Now I can hear you thinking - "but it works".
    Well sure, it "works" for a few iterations of your loop, but you're the one who is here and now all confused as to why your code suddenly blew up.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2016
    Posts
    4

    Exclamation Reply

    Quote Originally Posted by Salem View Post
    In two places, you have short allocated strings which have no \0 termination.

    Code:
        char *stringletter = malloc(sizeof(char));
        scanf("%s", &letter);
        *stringletter = letter;
    strcspn (used later) needs stringletter to have a \0.
    Otherwise, it might match garbage and give you a duff index to write to.

    Code:
        printf("%s\n", temp);
    Again, temp has no \0.

    Now I can hear you thinking - "but it works".
    Well sure, it "works" for a few iterations of your loop, but you're the one who is here and now all confused as to why your code suddenly blew up.
    Thanks for the advice. I tried it out, but now I have a different problem on my hands. Whenever a letter is inputted, when the loop runs again, the program doesn't take in another letter and then it seems the value of the letter variable changes to a value that isn't in the word variable, causing the player to lose a life right after they make an input:

    Code:
    1You have 5 lives.
    -------
    Put in a letter.
    p
    You guessed right.
    You have 5 lives.
    p------
    Put in a letter.
    You guessed wrong. You lose a life
    You have 4 lives.
    p------
    Put in a letter.
    This is the edited version of the code after I followed your advice:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) {
    
    char *word;
    
    
    int i = rand() % 2;
    printf("%d", i);
    
    switch(i) {
    
    case 0:
    word = "string";
    break;
    
    case 1:
    word = "program";
    break;
    
    }
    
    int length = strlen(word);
    char *temp = malloc( (length * sizeof(char)) + sizeof(char) );
    bool finished = false;
    int j;
    int lives = 5;
    char letter;
    char *stringletter = malloc(2*sizeof(char));
    
    for(j=0; j<(length); j++) {
    
    temp[j] = '-';
    
    }
    
    lives = 5;
    while(finished == false) {
        
        printf("You have %d lives.\n", lives);
        printf("%s\n", temp);
        printf("Put in a letter.\n");
        scanf("%c", &letter);
        *stringletter = letter;
        
        if( (strrchr(word, letter) != NULL) && (strrchr(temp,letter) == NULL) ) {
    
    
            int index = strcspn(word, stringletter);
            printf("You guessed right.\n");
            temp[index] = letter;
    
            for(j=0; j<length; j++) {
    
                if(word[j] == letter)
                    temp[j] = word[j];
    
            }
            
            continue;
    
        } else if(strrchr(word, letter) == NULL) {
    
            printf("You guessed wrong. You lose a life\n");
            --lives;
            
        } else {
    
            printf("You already have that letter. Try again.\n");
            continue;
        }
    
        if(strcmp(word, temp) == 0) {
    
            printf("You win! You guessed the word correctly. It's %s\n", word);
            break;
    }
        if(lives < 0) {
            printf("You're out of lives. You lose.\n");
            break;
        
    
        }
    
    
    
    }
    
    return 0;
    
    }
    Could you please explain why this is happening? The program seems to ignore the scanf command after it prints out "Put in a letter". Thanks for your help.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > scanf("%c", &letter);
    Put a space before the %c, so you get the next non whitespace character.

    At the moment, you're getting the newline as a character.

    > char *stringletter = malloc(2*sizeof(char));
    Your stringletter is still not \0 terminated.
    Try
    Code:
    char stringletter[2] = { '\0' };  // fills the array with \0
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jun 2016
    Posts
    4

    Talking Reply

    Quote Originally Posted by Salem View Post
    > scanf("%c", &letter);
    Put a space before the %c, so you get the next non whitespace character.

    At the moment, you're getting the newline as a character.

    > char *stringletter = malloc(2*sizeof(char));
    Your stringletter is still not \0 terminated.
    Try
    Code:
    char stringletter[2] = { '\0' };  // fills the array with \0
    It worked, thanks a lot. I have one question, though. Why was the program taking the newline character as the input, and why did putting a space before the %c make a difference?

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >I have one question, though. Why was the program taking the newline character as the input,
    Because the newline character is a character and %c consumes whitespace instead of ignoring it.

    >
    why did putting a space before the %c make a difference
    Because white space in a format string matches white space in the input.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Process return 10 (0xA) : while loop finishes suddenly
    By danielfdeus in forum C Programming
    Replies: 6
    Last Post: 09-25-2015, 04:59 PM
  2. Program suddenly stops working.
    By KittenAqua in forum C Programming
    Replies: 5
    Last Post: 10-18-2011, 05:45 AM
  3. Why are these pointers suddenly changed?
    By Adam Rinkleff in forum C Programming
    Replies: 5
    Last Post: 07-28-2011, 11:45 PM
  4. Replies: 5
    Last Post: 02-27-2010, 03:20 AM
  5. Replies: 5
    Last Post: 07-28-2009, 11:37 AM

Tags for this Thread