游戏士兵派遣功能递归校验失效问题排查求助
问题分析与修复方案
1. 递归调用的返回值未正确传递
generic_attack函数里,当输入的士兵数不符合要求时,你递归调用了自身,但没有把递归后的正确结果返回。比如第一次输入错误数值,递归后输入了正确值,但最终函数返回的还是第一次的错误数值,而且递归层级过深还可能触发栈溢出。
修复代码:
int generic_attack() { int soldiers; print_slowly("\nAlright! How many men should we send?\n"); print_soldiers(); print_slowly("You: Let's send "); scanf("%d", &soldiers); int check = wrong_soldiers_check(soldiers); if(check == 1){ return generic_attack(); // 直接返回递归调用的结果 } return soldiers; }
2. give_soldiers函数的缓冲区溢出与文件操作漏洞
- 数组长度不足:你定义了
char soldiers[3],但用fgets(soldiers, 4, soldiersp)读取,这会把终止符写到数组外部,造成缓冲区溢出,导致读取的士兵数值错乱,校验逻辑自然失效。 - 未检查文件是否打开成功:如果
soldiers.txt不存在或无法读取,fopen会返回NULL,此时调用fgets会直接程序崩溃。 - 数组容量不够存储正常数值:初始士兵数是450,属于3位数字,加上终止符至少需要4个字符的数组空间。
修复后的give_soldiers:
int give_soldiers() { FILE *soldiersp = fopen("soldiers.txt", "r"); // 检查文件是否成功打开 if(!soldiersp){ print_slowly("Failed to read soldier count!"); return 0; // 返回错误默认值,可根据需求调整 } // 足够存储多位数数值+终止符+换行符 char soldiers[10]; fgets(soldiers, sizeof(soldiers), soldiersp); fclose(soldiersp); return atoi(soldiers); }
3. scanf输入缓冲区残留问题
当用户输入非整数或超范围数值后,输入缓冲区里的无效字符会被下一次scanf直接读取,导致递归调用时跳过输入步骤,陷入无意义循环。需要手动清理缓冲区:
在scanf后添加清理代码:
scanf("%d", &soldiers); // 清理缓冲区中残留的无效字符 while(getchar() != '\n');
另外建议检查scanf的返回值,确保成功读取整数:
if(scanf("%d", &soldiers) != 1){ print_slowly("Invalid input! Please enter a number.\n"); while(getchar() != '\n'); // 清理缓冲区 return generic_attack(); }
内容的提问来源于stack exchange,提问作者a573263
相关产品推荐
相关产品推荐

