简体   繁体   English

我正在尝试在 C 中制作一个程序,您可以在其中玩刽子手,但一旦打印出猜测字母的选项,程序就会终止

[英]I'm trying to make a program in C in which you can play hangman but as soon as it prints the option to guess the letter the program terminates

The program isn't printing after giving me the first chance to guess.在给了我第一次猜测的机会后,程序没有打印出来。

#include <stdio.h>
#include <string.h>
int main() {
    char menu;
    int c = 0, flag = 0, life = 8;

    printf("\nWelcome to Hangman!!!");
    printf("\nThis is a game of hangman.");
    printf("Player 1 enters a random word and the other has to guess it.");
    printf("You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses.");
    printf("\n");
    printf("Press n for new game\n");
    printf("Press q to quit\n");
    printf("\n");

    scanf("%c", &menu);
    int i = 0, j = 0;
    char w[20], ch;

    if (menu == 'q') {
        printf("Exiting...");
        printf("Thanks for playing");
    }
    else if (menu == 'n') {
        printf("Player 1 enters a word\n");
        scanf("%s", w);
        int len = strlen(w);

        for (int i = 0; i < len; i++) {
            toupper(w[i]);
        }

        printf("\e[1;1H\e[2J");
        char arr[len - 1];

        for (int i = 0; i < len - 1; i++) {
            arr[i] = '_';
            printf("%c", arr[i]);
        }

        printf("\n");

        while (life != 0) {
            for (int i = 0; i < len - 1; i++) {
                if (arr[i] == '_') {
                    flag = 1;
                    break;
                }
                else {
                    flag = 0;
                }
            }

            if (flag == 0) {
                printf("You Won!!\n");
                printf("You Guessed The Word: %s", w);
                break;
            }
            else {
                char ans;
                printf("Enter a letter between A-Z");
                scanf("%c", ans);
                toupper(ans);
                
                for (int j = 0; j < len; j++) {
                    if (ans == w[j]) {
                        arr[j] = ans;
                        c++;
                    }
                }

                if (c == 0) {
                    life--;
                }

                c = 0;

                for (int j = 0; j < len; j++) {
                    printf("%c", arr[j]);
                }

                printf("\n Lives Remaining= %d \n", life);
            }
        }

        if (life == 0) {
            printf("\n You Lost!!! \n");
            printf("The Word Was: %s", w);
        }
    }
    else {
        printf("Invalid Character");
    }
}

Output: Output:
Welcome to Hangman!!!欢迎来到刽子手!!!
This is a game of hangman.Player 1 enters a random word and the other has to >guess it.You get 8 lives in total ie you can have a maximum of 8 wrong >guesses.这是一个刽子手游戏。玩家 1 输入一个随机单词,其他人必须 >猜测它。你总共获得 8 个生命,即你最多可以有 8 个错误 >猜测。
Press n for new game按 n 进入新游戏
Press q to quit按q退出

n n
Player 1 enters a word玩家 1 输入一个单词
Hello你好



Enter a letter between AZ PS C:\Users\arora\Desktop\Programs\C>在 AZ PS C:\Users\arora\Desktop\Programs\C> 之间输入一个字母

There are quite a few problems with your program.你的程序有很多问题。 Here are the major ones:以下是主要的:

  1. You want to use use space prefix in the format string for scanf(" %c", ...) to ensure previous newlines are ignored.您想在scanf(" %c", ...)的格式字符串中使用空格前缀,以确保忽略以前的换行符。
  2. scanf("%c", ans); should be &ans .应该是&ans It causes scanf() to fail and iterate through all guesses without additional data from user.它会导致scanf()失败并在没有来自用户的额外数据的情况下遍历所有猜测。 It also means no input was obtained from user so comparing it against word would never work.这也意味着没有从用户那里获得任何输入,因此将其与单词进行比较永远不会奏效。

Here are some of the other issues:以下是其他一些问题:

  1. #include <ctype.h> . #include <ctype.h>
  2. (not fixed) Consider changing the menu logic so 'q' quits, and any other letter starts a game. (不固定)考虑改变菜单逻辑,让“q”退出,任何其他字母开始游戏。
  3. Game prompt contains long lines that are hard to read for the player(s).游戏提示包含玩家难以阅读的长行。
  4. You use a printf() per line which makes it hard to read.您每行使用一个printf() ,这使得它难以阅读。 Use a single call and multi-line strings as input.使用单个调用和多行字符串作为输入。
  5. Try to branch your code less by making use of early return.尝试通过使用提前返回来减少您的代码分支。 It makes it easier to read.它使阅读更容易。
  6. Check the return value of scanf() .检查scanf()的返回值。 If it fails then whatever variable it read doesn't have a well defined value.如果它失败,那么它读取的任何变量都没有明确定义的值。
  7. Ensure that scanf() read no more than 19 bytes into a 20 byte array w .确保scanf()将不超过 19 个字节读取到 20 字节数组w中。 It takes a little macro magic to generate the 19 so I didn't make this change but it's a good idea to #define constants for magic values like the 20.生成 19 需要一点宏魔法,所以我没有进行此更改,但为 20 之类的魔法值#define常量是个好主意。
  8. arr is not \0 terminated (len-1). arr不是\0终止的 (len-1)。 Most c programmers expect a string so it's not worth the confusion to save 1 byte.大多数 c 程序员期望一个字符串,因此保存 1 个字节不值得混淆。
  9. Use a function or macro for the ANSI escape to clear the screen.使用 function 或宏进行 ANSI 转义以清除屏幕。
  10. Eliminate unused variables i , j .消除未使用的变量ij
  11. Reduce scope of variables (declare variables close to where you use them).减少变量的 scope(声明变量接近您使用它们的位置)。
  12. The calculation of the flag variable is cumbersome. flag变量的计算比较麻烦。
  13. (not fixed) The prompt "Enter a letter between AZ" is somewhat ambiguous. (未修复)提示“在 AZ 之间输入一个字母”有点模棱两可。 Suggest "... between A and Z".建议“...在 A 和 Z 之间”。
  14. It's generally a good idea to leave user input as you read.在阅读时留下用户输入通常是个好主意。 If you care about the repeated toupper() you can create a copy of the user input with letters in upper case, and create another variable to hold the upper case version of the player's guess.如果您关心重复的toupper() ,您可以创建一个用户输入的大写字母副本,并创建另一个变量来保存玩家猜测的大写版本。 This avoid you saying things like you entered the word "BOB" when the actual input was "bob".这样可以避免您在实际输入为“bob”时说出输入单词“BOB”之类的内容。
  15. You attempt to use toupper() to convert each letter to upper case but don't assign the result to anything so it does not do anything constructive.您尝试使用toupper()将每个字母转换为大写,但不将结果分配给任何内容,因此它不会做任何建设性的事情。
  16. Consider some functions to document what each your code does.考虑一些函数来记录每个代码的作用。 I added some comments for now.我现在添加了一些评论。
  17. (mostly not fixed) Consider using better variable names ( c , w , arr , flag ). (大多不固定)考虑使用更好的变量名( cwarrflag )。
  18. (not fixed) Should you reject a word with your magic '_' value? (不固定)你应该拒绝一个带有你神奇'_'值的词吗? In general should you validate that the word is reasonable (az, len > 0, len < 20)?一般来说,您是否应该验证该词是否合理(az、len > 0、len < 20)?
  19. (not fixed) If you guess a correct letter again, it's considered a good guess. (不固定)如果你再次猜对一个字母,它被认为是一个很好的猜测。 Should it?应该是?
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define clear() printf("\e[1;1H\e[2J")

int main() {
    printf(
        "Welcome to Hangman!!!\n"
        "\n"
        "This is a game of hangman.\n"
        "Player 1 enters a random word and the other has to guess it.\n"
        "You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses.\n"
        "\n"
        "Press n for new game\n"
        "Press q to quit\n"
    );
    char menu;
    if(scanf(" %c",&menu) != 1) {
        printf("scanf failed\n");
        return 1;
    }
    switch(menu) {
    case 'q':
        printf(
            "Exiting..."
            "Thanks for playing\n"
        );
        return 0;
    case 'n':
        break;
    default:
        printf("Invalid Character");
        return 1;
    }

    printf("Player 1 enters a word\n");
    char w[20];
    if(scanf("%19s", w) != 1) {
        printf("scanf failed\n");
        return 1;
    }
    clear();
    char arr[20];
    int len=strlen(w);
    for(int i=0;i<len;i++) {
        arr[i]='_';
    }
    arr[len] = '\0';
    int life=8;
    for(;;) {
        printf("%d Lives Remaining\n", life);

        // read a guess from player
        for(int i = 0; i < len; i++) {
            printf("%c", arr[i]);
        }
        printf(" Enter a letter between A-Z ");
        char guess;
        if(scanf(" %c", &guess) != 1) {
            printf("scanf failed\n");
            return 1;
        }

        // determine if any of the letters are in the secret word
        int c = 0;
        for(int i=0; i<len; i++) {
            if(toupper(guess) == toupper(w[i])) {
                arr[i]=guess;
                c = 1;
            }
        }
        if(c==0) {
            life--;
        }

        // game over?
        int flag = 0;
        for(int i = 0; i<len; i++) {
            if(arr[i]=='_') {
                flag=1;
                break;
            }
        }
        if(flag==0) {
            printf("You Won!!\n");
            printf("You Guessed The Word: %s\n",w);
            break;
        }
        if(life==0) {
            printf("\n You Lost!!!\n");
            printf("The Word Was: %s\n", w);
            break;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我正在尝试制作一个可以根据用户在 C 中的选择运行不同功能的程序 - I'm trying to make a program that can run different functions depending on the user's choice in C C中子手程序的麻烦 - trouble in hangman program in c 尝试制作一个程序来检查密码是否包含 c 中的大写字母和数字 - Trying to make a program that checks if a password contains uppercase letter and a number in c 我从客户端程序发送到服务器程序的消息打印在客户端程序 C Linux - Message which I sent from a client program to server program prints in client program C Linux 试图制作一个打印出首字母缩写词的程序 - Trying to make a program that prints out an acronym 我正在尝试制作一个顺时针旋转矩阵的程序,我认为指针存在一些问题 - I'm trying to make a program which rotated the matrix clockwise, and I think there's some problem with pointers 程序打印出所有输入的变量都被拒绝,但我试图让它只在输入特定字母时打印出来,例如'u'? - Program prints out declined for all variables entered, but I am trying to make it only print that out when a specific letter is entered e.g.'u'? 编程新手。 试图在 C 中编写一个程序,打印偶数直到 10。无法弄清楚逻辑错误 - New to programming. Trying to make a program in C that prints even numbers till 10. Can't figure out the logic error C 程序读取五个字符串并仅打印以字母“a”开头的字符串 - C program that reads five strings and only prints strings that begin with the letter 'a' 试图创建一个打印出所有有理平方根的数字的 C 程序? - Trying to create a C program which prints out all numbers with rational square roots?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM