【问题标题】:Hangman program string issue刽子手程序字符串问题
【发布时间】:2014-09-10 06:43:24
【问题描述】:

我正在上 C 编程入门课程,我们被分配编写一个 Hangman 程序。

在游戏中,计算机随机选择一个单词并显示它有多少个字母。用户必须通过输入他们认为可能在单词中的字母来猜测单词。此外,用户只有六次机会得到正确的单词。随着每一个错误的猜测,被绞死的图片将被完成。该程序需要有一个主菜单,其中包含三个选项(New gameScoreQuit)。程序还需要具备这三个功能:

  1. selectWord 随机选择单词(我在此函数中创建了一串单词)。
  2. drawMan 来画刽子手。
  3. checkWord 检查输入是否正确,并用正确的字母替换破折号。

我的问题发生在我运行游戏时,而不是显示虚线,虚线应该只是说 (null)。但图片仍然显示。

我很困惑可能是什么原因造成的。这是我目前所拥有的:

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

char selectWord(char []);
int drawMan(int);
void checkWord(char, char [], char [], int, int);

int main()
{
    int menuSelect;
    int chances = 0;
    char word[13];
    int length;
    int score;

    do
    {
        printf("\n\t\t\tThe Hangman Game v1.0 has booted\n\n");
        printf("\t\t[1]\t Create new game\n");
        printf("\t\t[2]\t View Score\n");
        printf("\t\t[3]\t Exit game\n");

        printf("Please enter a number from the menu: ");
        scanf("%d", &menuSelect);

        switch(menuSelect)
        {
            case 1:

                selectWord(word);
                length = strlen(word);

                char dash[20];    //Will create dashes considering the length of the selected word
                int dashCount;
                int letterTry; 
                int wordMatch = 0;

                for(dashCount = 0; dashCount < length; dashCount++)
                {
                    dash[dashCount] = '-';
                }
                dash[dashCount] = '\0';

                while(wordMatch != 1)
                {

                    drawMan(chances);

                    printf("\n%s", dash[dashCount]);
                    printf("\n\nPlease enter a letter: ");
                    fflush(NULL);

                    while(letterTry != '\n')
                    {
                        letterTry = getchar();
                    }
                    letterTry = getchar();

                    if(strcmp(dash, word) == 0)
                    {
                        printf("\nThat is correct!\n");
                        wordMatch = 1;
                        score++;
                    }
                }   

                break;

            case 2:

                printf("The score is: %d", score); 
                break;


            case 3:

                printf("Thank you for playing!");
                break;

        }       
    }while(menuSelect != 3);    
}

char selectWord(char word[])
{
    int index;
    char list[65][13]={{"sailboat"}, {"school"}, {"rug"}, {"chalk"}, {"tusk"}, {"camera"}, {"pajamas"}, {"cello"}, {"cake"}, {"beehive"}, {"gate"}, {"swing"}, {"lighthouse"}, {"toe"}, {"newspaper"}, {"stingray"}, {"brain"}, {"french"}, {"purse"}, {"soda"}, {"money"}, {"dryer"}, {"scale"}, {"clam"}, {"knee"}, {"artist"}, {"stomach"}, {"ticket"}, {"face"}, {"TV"}, {"can"}, {"blowfish"}, {"popsicle"}, {"beaver"}, {"snowball"}, {"dollar"}, {"sprinkler"}, {"hair"}, {"bathroom"}, {"rain"}, {"skirt"}, {"beach"}, {"suitcase"}, {"garden"}, {"doormat"}, {"pretzel"}, {"watering"}, {"fur"}, {"birthday"}, {"fries"}, {"owl"}, {"chin"}, {"spool"}, {"mushroom"}, {"peach"}, {"pelican"}, {"pineapple"}, {"flagpole"}, {"doghouse"}, {"boot"}, {"flute"}, {"quilt"}, {"hook"}, {"rainbow"}, {"happy"}};

    srand(time(NULL));
    index = rand()%65;

    strcpy(word, list[index]);

    return word;
}

int drawMan(int chances)
{
    if(chances == 6)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |        ");
        printf("\n         |        ");
        printf("\n         |");
        printf("\n         |");
        printf("\n        /|\\\n\n");
    }
    else if(chances == 5)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |       O");
        printf("\n         |       |");
        printf("\n         |");
        printf("\n         |");
        printf("\n        /|\\\n\n");
    }
    else if(chances == 4)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |       O");
        printf("\n         |      /|");
        printf("\n         |        ");
        printf("\n         |        ");
        printf("\n        /|\\\n\n");
    }
    else if(chances == 3)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |       O");
        printf("\n         |      /|\\");
        printf("\n         |        ");
        printf("\n         |        ");
        printf("\n        /|\\\n\n");
    }
    else if(chances == 2)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |       O");
        printf("\n         |      /|\\");
        printf("\n         |        ");
        printf("\n         |        ");
        printf("\n        /|\\\n\n");
    }
    else if(chances == 1)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |       O");
        printf("\n         |      /|\\");
        printf("\n         |      /");
        printf("\n         |        ");
        printf("\n        /|\\\n\n");
    }
    else if(chances == 0)
    {
        printf("\n\n");
        printf("\n         +-------+");
        printf("\n         |       |");
        printf("\n         |       O");
        printf("\n         |      /|\\");
        printf("\n         |      / \\");
        printf("\n         |        ");
        printf("\n        /|\\\n\n");
        printf("\n\n\t You have lost!");
    }
}
void checkWord(char ltrTry, char word[], char dash[], int length, int chances)
{
    int count;
    int correct = 0;    // 0 is incorrect 1 is correct

    for(count = 0; count < length; count++)
    {
        if(ltrTry == word[count])
        {
            dash[count] = word[count];
            correct = 1;            
        }
    }
}

更新 #1:感谢大家对破折号字符串的修复。向破折号数组添加空字符修复了破折号问题。我在名为“wordMatch”的主函数中为案例 1 添加了一个新变量,并将其作为 while 循环的控制变量,因为可以使单词正确并退出循环,而不会用尽所有机会。但似乎出现了一个新的。选择新游戏时,刽子手会显示两次,并且在输入错误的字母时,机会的数量不会改变,刽子手的形象也不会改变(给我无限次尝试)。然而,一旦我猜对了这个词,循环就会正确退出。为什么会发生这种情况?

更新 #2:我已更正代码并使其正常运行。现在唯一的问题似乎是 case 1 没有中断,因为它卡在了带有 letterTry 的 while 循环中。

【问题讨论】:

  • 我猜你错过了第二课 - 使用调试器
  • 这个人的输出逻辑在我看来没问题。请使用输出示例修改您的答案。
  • 顺便说一句 - 你会因为尝试而获得 +1,我会看看
  • 欢迎来到 StackOverflow!考虑隔离有问题的代码并发布显示错误所需的最少代码示例,而不是整个程序。粗略一瞥表明printf("\n%s", dash[dashCount]); 应该是printf("\n%s", dash);,它应该是\0 终止。
  • 请不要对您的问题进行重大更改,以完全改变问题并可能使现有答案无效。如果您解决了一个问题并遇到了新问题,请提出一个新问题。此外,在 SO 上表示感谢的最佳方式是为有用的答案投票并接受回答您问题的答案(您可以单击答案左侧的复选标记以接受)。

标签: c arrays string


【解决方案1】:

实际上有两个问题。分配破折号后,请确保使用\0 终止字符串,如下所示:

for(dashCount = 0; dashCount < length; dashCount++)
{
   dash[dashCount] = '-';
}
dash[dashCount] = '\0';

在while循环中,打印:

printf("\n%s", dash);

代替:

printf("\n%s", dash[dashCount]);

此外,您不会在每次尝试后更新 chances 值。您可以通过使checkWord 函数返回correct 并基于此更新机会计数来做到这一点,如下所示:

int checkWord(char ltrTry, char word[], char dash[], int length, int trys)
{
   ...

   return correct;
}

在循环中,不只是调用函数,而是执行以下操作:

if(!checkWord(letterTry, word, dash, length, chances))
{
   chances++;
}

我看到的另一个问题是在读取letterTry 值时。当您在之前使用scanf 函数后读取一个字符(在本例中为letterTry)时,\n 字符将存储在变量中。然后程序将不会提示您输入其他信息。在您的情况下,玩家将无缘无故失去一次机会。解决这个问题最简单的方法是:

while(letterTry != '\n')
   letterTry = getchar();

并且,一旦玩家得到正确答案,就从主循环中中断。

if(strcmp(dash, word) == 0)
   {
      printf("You Won!");
      score++;
      break;
   }

了解以上解决方案后,正确的,通过这个固定的解决方案:

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

char selectWord(char[]);
int drawMan(int);
int checkWord(char, char[], char[], int);

int main()
{
  int menuSelect;
  int chances = 0;
  char word[13];
  int length;
  int score;

  do
    {
      printf("\n\t\t\tThe Hangman Game v1.0 has booted\n\n");
      printf("\t\t[1]\t Create new game\n");
      printf("\t\t[2]\t View Score\n");
      printf("\t\t[3]\t Exit game\n");

      printf("Please enter a number from the menu: ");
      scanf("%d", &menuSelect);

      switch(menuSelect)
        {
        case 1:
          selectWord(word);
          length = strlen(word);

          char dash[20];    //Will create dashes considering the length of the selected word
          int dashCount;
          int letterTry; 

          for(dashCount = 0; dashCount < length; dashCount++)
            {
              dash[dashCount] = '-';
            }
          dash[dashCount] = '\0';

          chances = 0;
          while(chances != 6)
            {
              drawMan(chances);
              printf("\n%s\n", dash);
              printf("chances = %d\n", chances);
              printf("\n\nPlease enter a letter: ");
              fflush(NULL);
              //scanf("%c%c", &letterTry, &letterTry);
              while(letterTry != '\n')
                letterTry = getchar();
              letterTry = getchar();
              if(!checkWord(letterTry, word, dash, length))
                {
                  chances++;
                }
              if(strcmp(dash, word) == 0)
                {
                  printf("You Won!");
                  score++;
                  break;
                }
            }   
          break;
        case 2:
          printf("The score is: %d", score); 
          break;
        case 3:
          printf("Thank you for playing!");
          break;
        }       
    }while(menuSelect != 3);    
}

char selectWord(char word[])
{
  int index;
  char list[65][13]={{"sailboat"}, {"school"}, {"rug"}, {"chalk"}, {"tusk"}, {"camera"}, {"pajamas"}, {"cello"}, {"cake"}, {"beehive"}, {"gate"}, {"swing"}, {"lighthouse"}, {"toe"}, {"newspaper"}, {"stingray"}, {"brain"}, {"french"}, {"purse"}, {"soda"}, {"money"}, {"dryer"}, {"scale"}, {"clam"}, {"knee"}, {"artist"}, {"stomach"}, {"ticket"}, {"face"}, {"TV"}, {"can"}, {"blowfish"}, {"popsicle"}, {"beaver"}, {"snowball"}, {"dollar"}, {"sprinkler"}, {"hair"}, {"bathroom"}, {"rain"}, {"skirt"}, {"beach"}, {"suitcase"}, {"garden"}, {"doormat"}, {"pretzel"}, {"watering"}, {"fur"}, {"birthday"}, {"fries"}, {"owl"}, {"chin"}, {"spool"}, {"mushroom"}, {"peach"}, {"pelican"}, {"pineapple"}, {"flagpole"}, {"doghouse"}, {"boot"}, {"flute"}, {"quilt"}, {"hook"}, {"rainbow"}, {"happy"}};

  srand(time(NULL));
  index = rand()%65;

  strcpy(word, list[index]);

  return word;
}

int drawMan(int chances)
{
  if(chances == 0)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |        ");
      printf("\n         |        ");
      printf("\n         |");
      printf("\n         |");
      printf("\n        /|\\\n\n");
    }
  else if(chances == 1)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |       O");
      printf("\n         |       |");
      printf("\n         |");
      printf("\n         |");
      printf("\n        /|\\\n\n");
    }
  else if(chances == 2)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |       O");
      printf("\n         |      /|");
      printf("\n         |        ");
      printf("\n         |        ");
      printf("\n        /|\\\n\n");
    }
  else if(chances == 3)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |       O");
      printf("\n         |      /|\\");
      printf("\n         |        ");
      printf("\n         |        ");
      printf("\n        /|\\\n\n");
    }
  else if(chances == 4)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |       O");
      printf("\n         |      /|\\");
      printf("\n         |        ");
      printf("\n         |        ");
      printf("\n        /|\\\n\n");
    }
  else if(chances == 5)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |       O");
      printf("\n         |      /|\\");
      printf("\n         |      /");
      printf("\n         |        ");
      printf("\n        /|\\\n\n");
    }
  else if(chances == 6)
    {
      printf("\n\n");
      printf("\n         +-------+");
      printf("\n         |       |");
      printf("\n         |       O");
      printf("\n         |      /|\\");
      printf("\n         |      / \\");
      printf("\n         |        ");
      printf("\n        /|\\\n\n");
      printf("\n\n\t You have lost!");
    }
  printf("print complete; exiting successfully");
}

int checkWord(char ltrTry, char word[], char dash[], int length)
{
  int count;
  int correct = 0;    // 0 is incorrect 1 is correct

  for(count = 0; count < length; count++)
    {
      if(ltrTry == word[count])
        {
          dash[count] = word[count];
          correct = 1;            
        }
    }

  /*  if(correct == 0)
      {
      trys--;
      } */
  return correct;
}

【讨论】:

  • 谢谢你修复它!但现在看来,机会变量并没有改变值,给我无限的尝试,直到单词匹配。有什么可以解决的吗?
  • 谢谢Yedhu,刽子手部分现在工作正常,我已经相应地更新了原帖中的代码。现在唯一的问题似乎是 case 1 永远不会中断,因为带有 letterTry 和 getch() 的 while 循环不会停止。即使所有 6 次机会都用完了,或者即使我得到了正确的单词,它仍然会进入该循环并要求我输入一个新字母,显示的机会值会以 1 的增量变为负数。我感觉这可能是我的代码出错的最后一个问题。知道如何摆脱循环吗?
  • 随时欢迎您。我在if(strcmp(dash, word) == 0) 中添加了一个break 声明。请检查我在答案中添加的解决方案。我也会在描述中更新它。
猜你喜欢
  • 2021-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-04
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多