c - 我在刽子手游戏中比较两个字符串无法正常工作

标签 c strcmp strlen

我一直在为类类(class)制作一个刽子手游戏,我快完成了。但是,我偶然发现了一个似乎无法解决的问题。

首先,计算机从文本文件中选择一个随机单词,获取该单词的长度,并用该长度创建原始单词的屏蔽副本。然后比赛开始。玩家输入字母,如果在他/她失败六次之前完成该单词,他就获胜。否则,他/她就松了。我认为我的代码的问题是当我创建计算机选择的单词的掩码时,但我不确定。

如果我运行该程序,它看起来像这样:

选择的单词:strand (计算机选择的单词的第一个控制)

选择的单词:strand (第二个控制,查看是否将相同的单词从函数复制到主字符串中)

选择的单词:monster (这是由 free() 函数打印的。出于某种原因,它高了一个单词)

选择的单词:strand (在复制单词长度之前进行第三次控制,以查看复制的单词是否正确)

单词长度:6 (控制以查看长度是否与单词匹配,事实确实如此)

掩码:_ _ _ _ _ _ N (忽略下划线之间的空格,它们只是为了更容易看到。这就是我认为问题所在,因为最后添加了额外的字符,本例中为“N”。下划线的数量与字母的数量匹配,这很好)

掩码:_ _ _ _ _ _ N (由第二个 free() 函数打印)

然后,真正的游戏开始了。其他一切都工作正常(如果玩家中止或失败以及玩家想要或不想再次玩)。我检查了 int resultat (char* word, char* mask, int count) 函数中的实际 strcmp() 是否有效,并且确实有效。所以错误在于正在比较的字符串。我认为这是当我使用 strlen() 获取所选单词的长度时。当我得到长度时,我减去 1,因为否则我会得到一个太长的长度(例如,纸张给出的长度为 6,但当我减去 1 时,我得到 5)。

如果有人可以帮助我或者给我一些提示,我将非常感激!

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

#define MAX_WORD_LEN 20

char* datorns_val();
int ordlengd(char* word);
char* datorns_val_mask(char* word, int len);
int spel(char* word, char* mask, int len, int count, int result);
int resultat (char* word, char* mask, int count);
char get_user_choice();
void hangman(int count, int result);

const int MAX_GUESS = 6;
const char ABORT_CH = '0';
const int LOOSE = 0;
const int WIN = 1;
const int ABORTED = 2;

/************************************************************
 *
 *                       MAIN
 *
 *
 ************************************************************/

int main ()
{
    char word[MAX_WORD_LEN];
    char mask[MAX_WORD_LEN];
    int ch;
    int len;
    int result;
    int count;

    /*   -------------------- Programstart  -----------------*/

    srand(time(NULL));

    while (true) 
    { 
          result = 5;
          count = 0; 
          strcpy(word,datorns_val());
          printf("Valt ord 2: %s", word);
          free(datorns_val());
          len = ordlengd(word);
          strcpy(mask,datorns_val_mask(word,len));
          printf("\nMask 2: %s <-----", mask);
          free(datorns_val_mask(word,len));

          printf( "\nV\x84lkommen till HANGMAN 2014!\n");
          printf( "Du har %d gissningar p\x86 dig (avbryt med 0)\n", MAX_GUESS );
          printf( "Datorn har nu valt ett ord p\x86 %d bokst\x84ver\n", len );

          /* GAME MAIN LOOP */

          while (count < 6)
          {
                count=spel(word,mask,len,count,result);
                result=resultat(word,mask,count);
                hangman(count,result);
          }

          /* END MAIN GAME LOOP */

          if( result == WIN )
          {
              printf("\nGrattis du vann!\n");
          }
          else if( result == LOOSE )
          {
              printf("\nTyv\x84rr du f\x94rlorade! Ordet var: %s\n", word);
          }
          else
          {
              printf("Avbrutet\n");
          }     
          printf("Vill du spela igen? (j/n)");
          ch = get_user_choice();
          if (ch == 'n' || ch == 'N')
          {
                 break;
          }
    }
}
/***********************************************************
 *
 *  ---------        Funktionsdefinitioner ----------------
 *
 ***********************************************************/
char get_user_choice()
{
                  char tkn;
                  scanf(" %c", &tkn);
                  return tkn;
}
char* datorns_val()
{
    char ordlista[20];
    char* valt_ord = malloc(20);
    int random;
    int raknare = 0;
    random = rand()%4+1;
    FILE *ptr_file;
    ptr_file =fopen("hangman.dat","r");
    if (!ptr_file)
    {
                  printf("Filen kunde inte öppnas!");
    }
    while (fgets(ordlista,20, ptr_file)!= NULL)
    {
          if (raknare == random)
          {
                      strcpy(valt_ord, ordlista);
                      break;
          }
          raknare=raknare+1;
    }
    printf("Valt ord 1: %s",valt_ord);
    fclose(ptr_file);
    return valt_ord;
}
int ordlengd(char* word)
{
    printf("Valt ord 3: %s", word);
    int ordlengd;
    ordlengd=strlen(word)-1;
    printf("Ordlengd 1: %i", ordlengd);
    return ordlengd;
}
char* datorns_val_mask(char* word, int len)
{
     int j;
     char* gissning = malloc(20);
     for (j=0; j<len; j++)
     {
         gissning[j]='_';
     }
     printf("\nMask 1: %s <----", gissning);
     return gissning;
}
int spel(char* word, char* mask, int len, int count, int result)
{
     int j;
     char bokstav;
     int ratt = 0;
     printf("\nSkriv en bokstav: ");
     scanf(" %c", &bokstav);
     for(j=0; j<len; j++)
     {
              if(bokstav==word[j])
              {
                                  mask[j]=bokstav;
                                  ratt = 1;
              }
              else if(bokstav=='0')
              {
                   count = 7;
                   return count;
              }

     }
     if (ratt == 0)
     {
                    printf("\nBokstaven finns inte i ordet!\n");
                    count=count+1;
     }
     printf("Antal fel: %i\n\n", count);
     ratt = 0;
     for (j=0; j<len; j++)
     {
         printf("%c", mask[j]);
         printf(" ");
     }
     return count;
}
void hangman(int count, int result)
{
     const char* str[20]; 
     int j;   
     str[0]="\n_______ \n";
     str[1]="  | \n";
     str[2]="  O \n";
     str[3]="//|\\\\\n";
     str[4]="  | \n";
     str[5]="// \\\\\n";

     if(result != ABORTED)
     {
               for (j=0; j<count; j++)
               {
                   printf("%s", str[j]);
               }
     }
}
int resultat (char* word, char* mask, int count)
{
    char* a = "Hej";
    char* b = "Hej";
       if (count == 6)
       {
            return LOOSE;
       }
       else if (count < 6 && strcmp(mask,word) == 0)
       {
            return WIN;
       }
       else if (count == 7)
       {
           return ABORTED;
       }
}

最佳答案

代码中有一些内容:

1)第一个 free() 调用毫无意义:

free(datorns_val());

这会为字符串保留内存并在不使用它的情况下将其删除。所以摆脱它。

2) 使用 fgets() 从文件中读取字符串也会将行末尾的 '\n' 字符存储到字符串中,因此您必须删除它。作为提示,我用了这句话:

while(fscanf(ptr_file,"%s", ordlista) >0)

不存储“\n”字符。

3) 在 ordlengd(char* word) 函数中,您遇到了额外字符(上面提到的 '\n')的问题,因此长度与 strlen() 返回的长度相同,而不是

strlen(word) - 1 

你已经写了。

4) 你已经考虑过另一个条件来结束 main 函数的 while 循环。我建议添加

else return 5;

在 resultat() 函数末尾并在主函数的 while 循环中检查此值

while (count < 6 && result == 5)

希望对你有帮助

关于c - 我在刽子手游戏中比较两个字符串无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20991393/

相关文章:

c - 带地址运算符的 printf 字符串文字

C 结构体值在函数内部和外部不同

C - 更改 strtok 以合并 strcmp 后无输出打印

c++ - strspn C++ 下的奇怪行为,为什么?

c++ - 如何组合两个字符串?

c - 带有自旋锁的定时器卡住

c - 行和列的总和,每个元素为 1 或 0。 C

c++ - strcmp 总是在将字符串与反向进行比较时返回 0

c - Optarg 字符串比较 C

c++ - 连接命令行参数的最佳方法