单词争夺与数组中的指针。运行时崩溃

时间:2016-11-06 04:17:49

标签: c

我是带指针的数组的新手,我正在尝试制作一个指针数组争夺游戏,允许3次尝试在游戏结束前猜出这个单词。基本上,我创建了一个扰乱字符串的函数。然后,该字符串被发送到一个新的字符串,该字符串将显示给用户。然后用户输入他们的猜测。我的编译器没有收到任何错误信号。它只是在运行时崩溃。我相信错误是我发送指向方法的指针。有人可以告诉我为什么会发生这种错误吗?感谢。

#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;
}

2 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题:

1), scramble获得char *,但 scramWords[i] = words[i]; scramble(scramWords[i]);  您提供的是char,因此请将scramWords定义为char**,而不是char*

2)在声明指针时,您不会分配空间 - 这可能会导致段错误。使用malloc或访问指针之前。

3)将字符串从一个指针指向另一个时使用strcpy,而不是= operator

4)使用sizeof(words)/sizeof(*words)代替NUMWORDS = strlen(words);

这应该会给你留下一段代码,但正如评论中所说,请注意你的警告!

答案 1 :(得分:1)

  • 您不能尝试修改字符串文字,否则您将调用未定义的行为。在编辑字符串之前复制字符串而不是仅指定指针。
  • length - randomNum为0时,
  • length可能为randomNum
  • strlen(words)不会成为words中元素的数量。您可以使用sizeof(words) / sizeof(*words)
  • 在写任何内容之前,您必须先为scramWordsuser分配一些缓冲区。
  • 您不应该使用gets(),这有不可避免的缓冲区溢出风险,在C99中已弃用并从C11中删除。

试试这个:

#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;
}