开发Wordle克隆版遇指针类型不兼容等问题求助
Wordle克隆版开发问题解答
1. 编译错误修复
你遇到的编译错误核心是类型不匹配:check函数声明返回string*(即char**),但你用string(char*)类型变量result接收,两者类型不兼容。
更严重的隐患是:check函数里返回的letter是局部数组,函数执行结束后局部变量会被系统回收,返回它的指针会导致未定义行为(程序可能崩溃或输出乱码)。
解决思路:
- 放弃返回局部数组指针,改用主函数提前创建数组,作为参数传给
check函数填充结果(适合你当前未学习指针的阶段) - 同步修正
check函数的调用逻辑和返回类型
2. 合并结果为指定格式字符串
完全可行。可以先把每个字母的检查状态用整数编码(比如0=不在单词中,1=存在但位置错误,2=位置正确),再根据编码拼接成目标格式的字符串。
具体步骤:
- 生成每个字母的状态编码
- 分配足够大的字符串缓冲区(比如
char result[200]) - 用
sprintf逐个拼接每个字母的提示文本到缓冲区
3. 返回值选择:int数组 vs 字符串
优先选择int数组,原因:
- 内存占用更小:5个int仅20字节,远少于5个提示字符串的内存开销
- 灵活性更高:可根据int值轻松生成不同提示文本,或判断是否猜对单词
- 避免字符串指针的复杂问题,适配你当前的知识储备
修正后的完整代码
#include <cs50.h> #include <ctype.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <time.h> string word_list[] = { "blind", "sheet", "crush", "relax", "drain", "label", "expel", "thump", "shade", "resin", "alert", "dream", "flood", "guard", "adult", "force", "wound", "drain", "cable" }; string key; // 传入状态数组,填充每个字母的检查结果:0=不在单词,1=存在位置错,2=位置正确 void check(string guess, string key, int status[]); int main(void) { char ready; do { ready = get_char("Welcome to wordle! Are you ready to play? (y/n) "); } while (ready != 'n' && ready != 'y'); // 用字符常量更易读,无需记忆ASCII码 if (ready == 'y') { srand(time(NULL)); int ran = rand() % 18; key = word_list[ran]; } else { return 1; } int guess_num = 1; string guess[5]; // 存储5次猜测的单词 int status[5]; // 存储每次猜测的字母状态 char result_str[200]; // 存储最终拼接的提示字符串 for (int i = 0; i < 5; i++) { do { guess[i] = get_string("Guess %i:\n", guess_num); if (strlen(guess[i]) != 5) { printf("请输入5个字母的单词!\n"); continue; } // 调用check函数填充状态数组 check(guess[i], key, status); // 拼接结果字符串 strcpy(result_str, ""); // 清空缓冲区 for (int j = 0; j < 5; j++) { char part[50]; switch(status[j]) { case 2: sprintf(part, "第%d个字母:位置正确,", j+1); break; case 1: sprintf(part, "第%d个字母:在单词中但位置错误,", j+1); break; case 0: sprintf(part, "第%d个字母:不在单词中,", j+1); break; } strcat(result_str, part); } // 移除末尾多余的逗号和空格 result_str[strlen(result_str)-2] = '\0'; printf("%s\n", result_str); // 判断是否猜对单词 int is_win = 1; for (int j = 0; j < 5; j++) { if (status[j] != 2) { is_win = 0; break; } } if (is_win) { printf("恭喜你猜对了!\n"); return 0; } guess_num++; } while (strlen(guess[i]) != 5); } printf("游戏结束!正确单词是:%s\n", key); return 0; } void check(string guess, string key, int status[]) { // 初始化状态为0(不在单词中) for (int i = 0; i < 5; i++) { status[i] = 0; } // 第一步:检查位置完全匹配的字母 for (int i = 0; i < 5; i++) { if (guess[i] == key[i]) { status[i] = 2; key[i] = toupper(key[i]); // 转大写标记为已匹配,避免重复判断 } } // 第二步:检查存在但位置错误的字母 for (int i = 0; i < 5; i++) { if (status[i] == 2) continue; // 跳过已匹配正确的字母 for (int j = 0; j < 5; j++) { if (guess[i] == tolower(key[j])) { status[i] = 1; key[j] = toupper(key[j]); // 标记为已匹配 break; } } } // 恢复key的原始小写状态 for (int i = 0; i < 5; i++) { key[i] = tolower(key[i]); } }
内容的提问来源于stack exchange,提问作者Charlie Webster
相关产品推荐
相关产品推荐

