【问题标题】:Convert input to uppercase in a game在游戏中将输入转换为大写
【发布时间】:2020-04-07 16:22:45
【问题描述】:

我编写了一个非常简单的 Hangman 游戏,它要求用户输入,然后让用户猜六次。 始终显示单词的第一个字母,如果用户输入了已经发现的相同字母,则不会被视为错误, 如果刽子手字符串由大写字母组成,我想改进我的代码以使其接受小写输入。 例如,如果输入字符串是“HELLO”并且用户在控制台上看到这个 H____ 并且他输入了小写字母“e”,那么该字母应该不被覆盖并作为输入字符串打印为大写字母。 因此,在用户输入 e 后,输出应如下所示 HE___ 然而,按照我实现的方式,它只是将所有大写字母转换为小写字母。

如果字符串中有大写字母,如何让代码接受小写用户输入并打印出大写用户输入?

感谢您的帮助

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

int main(void)
{
    char hangmanWord[100], tempWord[100];      
    char hangmanOutput[100];                    
    int wrongTry = 6 , matchFound = 0;         
    int tries = 0;                             
    int counter = 0 , position = 0, winner, length , i;
    char alphabetFromUser;
    scanf("%s",hangmanWord);

    getchar();
    length = strlen(hangmanWord);

     for( i = 1; i < length ; i++)
    {   
        hangmanOutput[i] = '_';
        hangmanOutput[length] = '\0';
    }

    for(i = 0 ; i < length ; i++)

    {   

        if(i==0){
        printf("%c",hangmanWord[0]);

        }

        printf("%c",hangmanOutput[i]);  //line output 

         if(i==length-1){
             printf("(%d)",tries);
         }

    }

    while(wrongTry != 0)                        /**while loop for exiting the program when no try left**/
    {
        matchFound = 0;
        putchar('\n');
        printf("letter: ");
        scanf("%c",&alphabetFromUser);
        fflush(stdin);
        if (matchFound != 2)
    {
        for(counter=0;counter<length;counter++)    /**for loop to check whether player input alphabet exists or not in the word**/
        {

            if(hangmanWord[counter]>= 'A' && hangmanWord[counter] <= 'Z'){

                hangmanWord[counter] = tolower(hangmanWord[counter]);
                 }

            if(alphabetFromUser==hangmanWord[counter])
             {
               matchFound = 1;
                     }//end of if()
            }//end of

     if(matchFound == 0)                      /**in case of wrong guess**/
        {
             wrongTry--;
             tries++;
        }//en
    else
       {
         for(counter = 0; counter < length; counter++)
             {
                 matchFound = 0;
                 if(alphabetFromUser == hangmanWord[counter])
              {
                 position = counter ;
                 matchFound = 1;
              }//end of if
              if(matchFound == 1)
              {
                 for(i = 0 ; i < length ; i++)
                 {
                      if( i == position)
                      {
                          hangmanOutput[i] = alphabetFromUser; /**Put the alphabet at right position**/
                      }
                      else if( hangmanOutput[i] >= 'a' && hangmanOutput[i] <= 'z' ) /** If the position already occupied
                                                                                  by same alphabet then no need to
                                                                                  fill again EASY!! and continue */
                      {
                          continue;
                      }

                      else
                      {
                          hangmanOutput[i] = '_';            /** Put a underscore at not guessed alphabet position **/
                      }
                }

                 tempWord[position] = alphabetFromUser;      /**put the alphabet in another char array to check with the original word**/
                tempWord[length] = '\0';   
                             /**put the NULL character at the end of the temp string**/
                winner = strcmp(tempWord+1,hangmanWord+1);      /**upon True comparison it will return 0**/

                if(winner == 0)                             /**if the player guessed the whole word right then he/she is the WINNER**/
                {
                    for(i = 0 ; i < length ; i++)

    {   
        if(i==0){
        printf("%c",hangmanWord[0]);

        }

        printf("%c",hangmanOutput[i+1]);  //line output  
         if(i==length-1){
             printf("(%d)",tries);
         }
    }     
                    getchar();
                    return 0;
                }//end of inner if
           }//end of outer if
        }//end of for loop
      }//end of else
    } // end of if(matchFound != 2) condition

for(i = 0 ; i < length ; i++)
    {   
        if(i==0){
        printf("%c",hangmanWord[0]);

        }

        printf("%c",hangmanOutput[i+1]);  //line output  
         if(i==length-1){
             printf("(%d)",tries);
         }
    }
    getchar();
    }

          if(wrongTry <= 0)                                 /**if the player can not guess the whole word in 5 chaces**/
      {
          putchar('\n');
          printf("DEAD\n");
          return 0;
      }
getchar();
    return 0;
}

【问题讨论】:

  • 请修正缩进并删除不必要的空行。
  • toupper() 函数的名称中有“upper”以提醒您它的作用。
  • 我知道 toupper 函数。但我在想我会先检查字符串中是否有大写字母,然后使用降低,以便我可以将它与输入进行比较。但我不知道在我的代码中哪里可以实现 toupper() 函数,以便在比较后再次使字符变大
  • 您的问题相当清楚,但包含不必要的细节。涉及游戏逻辑的代码部分与您的实际问题无关。您可以提出一个非常短的问题,重点关注如何利用输入。请阅读如何制作minimal reproducible example
  • 您将输入转换为大写以匹配您的工作文本。如果用户输入小写,您不会将工作文本转换为小写;他们可能输入了大写字母。

标签: c arrays string uppercase lowercase


【解决方案1】:

查看ascii table,az 中的小写字母从 0x6_ 到 0x7_,大写字母从 0x4_ 到 0x5_,这意味着我们要做的就是关闭第二个半字节的第二位以便将小写字母转换为大写字母。

(a) a-z 如下 0110 xxxx, 0111 xxxx

(b) A-Z 如下 0100 xxxx, 0101 xxxx

假设我们有字符“a”,即 0110 xxxx。如果我们使用 AND 按位与 0x5F => 0110 xxxx & 0101 xxxx => 0100 xxxx => 'A'

char upper(char ch) {
   return(ch & 0x5F);
}

现在我们有了函数,我们可以使用它了。查看您的代码,您将检查 hangman 数组两次,以防用户输入了小写字母或大写字母,因此我们可以这样做一次

 int32_t right_letter;
 int32_t tries;
 int32_t win;

 right_letter = 0;

 /* since one letter is already discovered */
 win          = length - 1;


 while(wrongTry != 0) {

     /* read from user */

     for(counter = 0; counter < length; ++counter) {

         if(hangmanOutput[counter] == '_'){

            if(upper(alphabetFromUser) == upper(hangmanWord[counter])) {

                hangmanOutput[counter] = hangmanWord[counter];

                right_letter = 1;

                ++win;

            }

        }

    if(win + 1 == length)
        /* win */

    wrongTry -= !right_letter;

    right_letter = 0;

}

我还没有测试过代码,但它应该可以工作。试着了解我改变了什么以及为什么。

编辑:@Andrew Henle 在 cmets 中提到 OP 没有指定字符集,因此我认为它是 ASCII。

【讨论】:

  • 字符集不一定是 ASCII。
  • 恕我直言,如果我是 OP,我肯定会在阅读该答案后更加困惑,而不是在 Stack Overflow 中发布我的问题之前。 ://
  • @AndrewHenle 是的。感谢提及。我已经编辑了我的帖子。
  • @VioAriton 我已经测试了你的代码。即使我阅读了用户的输入,它也不会进入游戏
【解决方案2】:

对于仅 ASCII 的输入,这很简单......只需利用 C 中的 char 类型实际上可以用作 int 的事实并进行数学运算。

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

int main(){
  char ch;
  printf("letter : ");
  ch = getc(stdin);

  if (ch >= 'a' && ch <= 'z')
    ch -=32;
  else if (ch >= 'A' && ch <= 'Z')
    ch += 32;

  printf("output : %c\n", ch);

  return 0;
}

下面给出另一个版本。您可以将lower_caseupper_case 替换为您想要的任何其他字母,然后就可以了。

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

char convert(char ch){
  const char *lower_case = "abcdefghijklmnopqrstuvwxyz";
  const char *upper_case = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  char *p;

  if ((p = strchr(lower_case, ch)) != NULL)
    return *(upper_case+(p-lower_case));
  else if ((p = strchr(upper_case, ch)) != NULL)
    return *(lower_case+(p-upper_case));
  else
    return ch;
}

int main(){
  char ch;
  printf("letter : ");
  ch = getc(stdin);

  printf("output : %c\n", convert(ch));

  return 0;
}

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多