You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

游戏士兵派遣功能递归校验失效问题排查求助

问题分析与修复方案

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:33:32