控制台猜单词:程序挑一个词,显示下划线遮罩,你逐字母猜,猜错 6 次小人就吊死。练的是字符数组、状态标记和字符串处理。

1. 选词与遮罩

单词表用字符指针数组;选中的词复制到 word,遮罩数组 mask 初始全为 '_',猜中就把对应位置换成字母:

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

const char *pool[] = {"python", "keyboard", "monitor", "mouse", "camera",
                      "guitar", "rocket", "planet", "winter", "garden"};
#define WORDS (int)(sizeof(pool) / sizeof(pool[0]))

char word[32], mask[32];

void pick_word(void) {
    strcpy(word, pool[rand() % WORDS]);
    int len = (int)strlen(word);
    for (int i = 0; i < len; i++) mask[i] = '_';
    mask[len] = '\0';
}

void reveal(char ch) {
    for (int i = 0; word[i]; i++)
        if (word[i] == ch) mask[i] = ch;
}

2. 猜错计数与 ASCII 小人

猜错一次 wrong++,用字符串数组画 6 个阶段的小人。猜中全部字母就赢:

const char *stages[] = {
    "  +---+\n      |\n      |\n      |\n      |\n=========",
    "  +---+\n  O   |\n      |\n      |\n      |\n=========",
    "  +---+\n  O   |\n  |   |\n      |\n      |\n=========",
    "  +---+\n  O   |\n /|   |\n      |\n      |\n=========",
    "  +---+\n  O   |\n /|\\  |\n      |\n      |\n=========",
    "  +---+\n  O   |\n /|\\  |\n /    |\n      |\n=========",
    "  +---+\n  O   |\n /|\\  |\n / \\  |\n      |\n=========",
};

int all_guessed(void) {
    for (int i = 0; word[i]; i++)
        if (mask[i] == '_') return 0;
    return 1;
}

3. 完整代码

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

const char *pool[] = {"python", "keyboard", "monitor", "mouse", "camera",
                      "guitar", "rocket", "planet", "winter", "garden"};
#define WORDS (int)(sizeof(pool) / sizeof(pool[0]))

char word[32], mask[32];

const char *stages[] = {
    "  +---+\n      |\n      |\n      |\n      |\n=========",
    "  +---+\n  O   |\n      |\n      |\n      |\n=========",
    "  +---+\n  O   |\n  |   |\n      |\n      |\n=========",
    "  +---+\n  O   |\n /|   |\n      |\n      |\n=========",
    "  +---+\n  O   |\n /|\\  |\n      |\n      |\n=========",
    "  +---+\n  O   |\n /|\\  |\n /    |\n      |\n=========",
    "  +---+\n  O   |\n /|\\  |\n / \\  |\n      |\n=========",
};

void pick_word(void) {
    strcpy(word, pool[rand() % WORDS]);
    int len = (int)strlen(word);
    for (int i = 0; i < len; i++) mask[i] = '_';
    mask[len] = '\0';
}

void reveal(char ch) {
    for (int i = 0; word[i]; i++)
        if (word[i] == ch) mask[i] = ch;
}

int all_guessed(void) {
    for (int i = 0; word[i]; i++)
        if (mask[i] == '_') return 0;
    return 1;
}

int main(void) {
    srand((unsigned)time(NULL));
    pick_word();
    int wrong = 0;
    char guessed[26] = {0};
    int gcnt = 0;
    printf("===== 猜单词 =====\n");
    while (wrong < 6 && !all_guessed()) {
        printf("%s\n单词: %s  猜错 %d/6\n", stages[wrong], mask, wrong);
        printf("猜一个字母: ");
        fflush(stdout);
        char ch;
        scanf(" %c", &ch);
        int dup = 0;
        for (int i = 0; i < gcnt; i++)
            if (guessed[i] == ch) dup = 1;
        if (dup) { printf("这个猜过了!\n"); continue; }
        guessed[gcnt++] = ch;
        if (strchr(word, ch)) { reveal(ch); printf("对了!\n"); }
        else { wrong++; printf("错了!\n"); }
    }
    if (all_guessed()) printf("\n恭喜!单词是 %s\n", word);
    else printf("%s\n吊死了!单词是 %s\n", stages[wrong], word);
    return 0;
}

4. 运行与常见问题

保存为 hangman.c,gcc hangman.c -o hangman 后运行。常见问题:①重复字母不计数——用 guessed 数组去重;②输入大写没反应——统一转小写(tolower);③反斜杠乱码——画小人时 \\ 在 C 里要写 \\\\。

💡 改进方向:①难度分级;②分类词库(动物/编程);③提示系统;④计分(猜得越快越高);⑤支持中文词。