Submersed24 Submersed24 - 29 days ago 16
C Question

word scramble with pointers in an array. Does not compile

I am new to arrays with pointers, and I am trying to make an array of pointers word scramble game that allows 3 tries to guess the word before the game ends. Basically, I have created a function that scrambles a string. Then, that string is sent to a new string, which is shown to the user. The user then enters their guess. I am getting no signal from my compiler on what is wrong.. It just crashes when it is run. I believe the error is when I am sending the pointer to the method. Could someone please tell me why this error is happening? Thanks.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

void scramble(char *strings)
{
int length = strlen(strings), i, randomNum;
char temp;

for(i = 0; i < length/2; i++)
{
randomNum = rand()%length;
temp = strings[i];
strings[i] = strings[length - randomNum];
strings[length - randomNum] = temp;
}
}

int main()
{
int i, tries, NUMWORDS;
char *words[] = { "pumpkin", "cantalope", "watermelon", "apple", "kumquat" };
char *scramWords, *user;
NUMWORDS = strlen(words);
srand(time(NULL));
for(i = 0; i < NUMWORDS; i++)
{
scramWords[i] = words[i];
scramble(scramWords[i]);
}

printf("How to play: You get 3 tries to guess each scrambled word.\n");
for(i = 0; i < NUMWORDS; i++)
{
tries = 0;
while(tries !=4)
{
if(tries == 3)
{
printf("You Lose\n");
return 0;
}
printf("Unscramble: %s\n", scramWords[i]);
gets(user);
if(strcmp(user, words[i]) == 0)
{
printf("Correct!\n");
break;
}
else
{
tries++;
}
}
}
printf("You Win!");

return 0;
}

Answer
  • You must not try to modify string literals, or you will invoke undefined behavior. Copy strings before editing them instead of just assigning pointers.
  • length - randomNum may be length when randomNum is 0.
  • strlen(words) won't be the number of elements in words. You can use sizeof(words) / sizeof(*words).
  • You must allocate some buffer to scramWords and user before writing anything there.
  • You shouldn't use gets(), which has unavoidable risk of buffer overrun, deprecated in C99 and removed from C11.

Try this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

void scramble(char *strings)
{
    int length = strlen(strings), i, randomNum;
    char temp;

    for(i = 0; i < length/2; i++)
    {
        randomNum = rand()%length;
        temp = strings[i];
        strings[i] = strings[length - randomNum - 1];
        strings[length - randomNum - 1] = temp;
    }
}

int main(void)
{
    int i, tries, NUMWORDS;
    char *words[] = { "pumpkin", "cantalope", "watermelon", "apple", "kumquat" };
    char **scramWords, user[1024], *lf;
    NUMWORDS = sizeof(words) / sizeof(*words);
    srand(time(NULL));
    scramWords = malloc(sizeof(*scramWords) * NUMWORDS);
    if(scramWords == NULL)
    {
        perror("malloc");
        return 1;
    }
    for(i = 0; i < NUMWORDS; i++)
    {
        scramWords[i] = malloc(strlen(words[i]) + 1); /* +1 for terminating null-character */
        if(scramWords[i] == NULL)
        {
            perror("malloc");
            return 1;
        }
        strcpy(scramWords[i], words[i]);
        scramble(scramWords[i]);
    }

    printf("How to play: You get 3 tries to guess each scrambled word.\n");
    for(i = 0; i < NUMWORDS; i++)
    {
        tries = 0;
        while(tries !=4)
        {
            if(tries == 3)
            {
                printf("You Lose\n");
                return 0;
            }
            printf("Unscramble: %s\n", scramWords[i]);
            if(fgets(user, sizeof(user), stdin) == NULL)
            {
                puts("fgets failed");
                return 1;
            }
            if((lf = strchr(user, '\n')) != NULL)
            {
                *lf = '\0'; /* remove newline character after string read */
            }
            if(strcmp(user, words[i]) == 0)
            {
                printf("Correct!\n");
                break;
            }
            else
            {
                tries++;
            }
        }
    }
    printf("You Win!");

    return 0;
}
Comments