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

C语言My_Mastermind小游戏超4位数字输入校验失效问题求助

问题描述

C语言实现My_Mastermind猜数字小游戏时,输入校验逻辑存在不符合设计规则的异常:

  • 游戏要求玩家输入的猜测密码必须为严格4位数字
  • 输入不足4位数字(如123)时,程序可正常触发错误提示,表现符合预期
  • 输入长度超过4位的数字串(如5位的01234、6位及更长内容)时,程序未抛出输入错误,反而直接截取输入前4位字符执行游戏逻辑,违反设计要求
根因定位

逐行排查逻辑后,定位到4个直接/关联缺陷:

  1. 校验顺序倒置:用户输入读取完成后,程序先调用size_of_function强制截取前4位字符,再将截断后的内容传入校验函数,超长输入在进入校验环节前已经被裁为4位,长度校验完全失效
  2. 长度校验代码被注释:wrong_input函数中用于判断输入长度是否为4位的代码块被整段注释,没有执行
  3. 输入读取逻辑存在漏洞:input_function使用read读取标准输入时,没有将用户输入末尾的换行符替换为字符串结束符\0,会导致my_strlen计算长度时出现随机偏差
  4. 附加逻辑bug:mis_placed_pieces(错位数字统计)函数循环逻辑错误,i从0开始先自增再判断,会跳过第0位元素、越界访问数组第4位内存,统计结果完全错误
修复方案

针对上述问题逐一修复:

  • 调整校验顺序:拿到原始用户输入后,先完成长度、字符合法性校验,校验通过后再提取有效4位内容传入后续游戏逻辑
  • 补全长度校验:在数字字符校验前增加长度判断,有效长度不等于4位直接判定为非法输入
  • 修复输入读取逻辑:读取输入后遍历字符串,将末尾换行符替换为\0,确保字符串终止正确,长度计算准确
  • 修正错位数字统计逻辑,避免数组越界,同步修复已知内存泄漏问题
修复后完整代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
typedef struct s_mastermind {
    int my_attempt;
    char* my_code;
} my_mastermind;

my_mastermind* settings_function(my_mastermind* mastermind, int argc, char** argv);
int checking_for_correctness_num(char* _string, int len);
int wrong_input(int progress,char* num_code);
my_mastermind* my_function();
int check_function(char* string);
char* input_function();
int mis_placed_pieces(char* bit, char* num_code);
int well_placed_pieces(char* bit, char* num_code);
int code_checker(char* bit, char* num_code);
char* get_valid_code(char* strye);

int my_strlen(char* num1) {
    return (*num1) ? my_strlen(++num1) + 1 : 0;
}

char* my_strcpy(char* num1, char* num2) {
   for(int i = 0; num2[i] != 0; i++) {
       num1[i] = num2[i];
   }
   num1[my_strlen(num2)] = '\0';
   return num1;
}

my_mastermind* my_function() {
    my_mastermind* num = malloc(sizeof(my_mastermind));
    num->my_code = malloc(5);
    num->my_code[4] = '\0';
    my_strcpy(num->my_code, "0000");
    num->my_attempt = 10;
    return num;
}

my_mastermind* settings_function(my_mastermind* mastermind, int argc, char** argv) {
    for(int i = 0; i < argc; i++) {
        if (my_strlen(argv[i]) == 2 && argv[i][0] == '-') {
            if(argv[i][1] == 'c') {
                if(i+1 >= argc) break;
                char* num_code = argv[i + 1];
                if(wrong_input(argc,num_code) != 0) {
                    break;
                }
                my_strcpy(mastermind->my_code, num_code);
            }else if(argv[i][1] == 't') {
                if(i+1 >= argc) break;
                if(checking_for_correctness_num(argv[i + 1], my_strlen(argv[i+1])) == 0) {
                    mastermind->my_attempt = check_function(argv[i + 1]);
                }
            } else {
                printf("WRONG FLAG RESTART THE GAME!!!\n");
            }
        }
    }
    return mastermind;
}

int wrong_input(int progress,char* num_code) {
    int len = my_strlen(num_code);
    if(len != 4) {
        printf("Wrong input! Please enter exactly 4 digits.\n> ");
        fflush(stdout);
        return 1;
    }
    if(checking_for_correctness_num(num_code, len) == 1) {
        printf("Wrong input! Please enter valid digits.\n> ");
        fflush(stdout);
        return 1;
    } 
    return 0;
}

int checking_for_correctness_num(char* _string, int len) {
    for(int i = 0; i < len; i++) {
        if(!(_string[i] >= '0' && _string[i] <= '9')) {
            return 1;
        }
    }
    return 0;
}

int check_function(char* string) {
    int check_num = 0;
    for(int i = 0; string[i] != '\0'; i++) {
        check_num = check_num * 10 + (string[i] - '0');
    }
    return check_num;
}

char* input_function() {
    char* getting = malloc(101);
    int read_len = read(0, getting, 100);
    for(int i = 0; i < read_len; i++) {
        if(getting[i] == '\n') {
            getting[i] = '\0';
            break;
        }
    }
    getting[read_len] = '\0';
    fflush(stdout);
    return getting;
}

int game_progress(int progress, char* bit) {
    printf("Round: %d\n> ", progress);
    fflush(stdout);
    char* code = input_function();
    int results = 1;
    if(wrong_input(progress,code) == 0) {
        char* valid_code = get_valid_code(code);
        results = code_checker(bit, valid_code);
        free(valid_code);
    }
    free(code);
    return results;
}

void game_action(my_mastermind* mastermind) {
    int current_try = 0;
    for (;current_try < mastermind->my_attempt;) {
        int results = game_progress(current_try, mastermind->my_code);
        current_try += 1;
        if(results == 0) {
            printf("Congratz! You did it!\n");
            break;
        }
    }
}

int code_checker(char* bit, char* num_code) {
    int good_w = well_placed_pieces(bit, num_code);
    int not_good_m = mis_placed_pieces(bit, num_code);
    if(good_w > 0 || not_good_m > 0){
        printf("Well placed pieces: %d\nMisplaced pieces: %d\n---\n", good_w,not_good_m);    
    }
    if(good_w == 4) {
        return 0;
    } else {
        return 1;
    }
}

int well_placed_pieces(char* bit, char* num_code) {
    int number = 0;
    for(int i = 0; i < 4; i++) {
        if (bit[i] == num_code[i]) {
            number += 1;
        } 
    }
    return number;
}

int mis_placed_pieces(char* bit, char* num_code) {
    int number = 0;
    int used_bit[4] = {0};
    int used_code[4] = {0};
    for(int i = 0; i <4; i++) {
        if(bit[i] == num_code[i]) {
            used_bit[i] = 1;
            used_code[i] = 1;
        }
    }
    for(int i = 0; i <4; i++) {
        if(used_bit[i]) continue;
        for(int j = 0; j<4; j++) {
            if(!used_code[j] && bit[i] == num_code[j]) {
                number++;
                used_code[j] = 1;
                break;
            }
        }
    }
    return number;
}

char* get_valid_code(char* strye) {
    char* new_string = malloc(5);
    new_string[4] = '\0';
    for(int i = 0; i < 4;i++){
        new_string[i] = strye[i];
    }
    return new_string;
}

int main(int argc, char** argv) {
    printf("Will you find the secret code?\n---\n");
    my_mastermind* mastermind = my_function();
    settings_function(mastermind, argc, argv);
    game_action(mastermind);
    free(mastermind->my_code);
    free(mastermind);
    return 0;
}
修复验证

修复后测试表现符合设计要求:

  • 输入3位数字:触发错误提示,要求输入4位数字
  • 输入5位及以上数字:触发错误提示,要求输入4位数字
  • 输入含非数字字符:触发错误提示,要求输入合法数字
  • 输入严格4位数字:正常进入比对逻辑,正确输出对位、错位统计结果
  • 所有动态申请的内存均正确释放,无内存泄漏问题

内容的提问来源于stack exchange,提问作者Alucard11123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:45:46