C语言彩票选号程序:数组重复整数检测功能故障排查
彩票游戏代码的问题分析及修复方案
你的代码主要存在三个核心问题,导致无法正常完成输入校验和重复检测:
1. checkIfContains 函数逻辑完全错误
这个函数是重复检测的核心,但两个致命错误导致它完全失效:
- 循环从
i=1开始,直接跳过数组第一个元素(索引0),永远无法检测第一个输入的数字是否重复。 - 循环内第一次比较就直接返回结果:如果
arrayToCheck[i]不等于目标数字,立刻返回false,根本没遍历整个数组,无法发现后续位置的重复值。
修复后的函数:
bool checkIfContains(int digit, int arrayToCheck[], int len, int currentIndex) { // 只检查当前索引之前的元素,避免和自身对比导致误判 for (int i = 0; i < currentIndex; i++) { if (arrayToCheck[i] == digit) { return true; } } return false; }
新增currentIndex参数的目的是:检查当前输入的数字时,只需要和已经输入完成的前面的元素对比,不需要和自身或者未输入的元素比较,避免把当前元素自己当成重复值。
2. enterRow 函数的校验流程漏洞
- 重复检测调用错误:原代码调用
checkIfContains时,把当前元素和整个数组对比,包括它自己,导致第一个元素会被误判为重复(因为数组里存在它本身)。 - flag变量逻辑混乱:原代码中只要有一个元素通过校验就设置
flag=2,但如果后续元素非法,flag已经被设为2,循环会直接退出,导致非法输入被保留。 - 错误提示后的流程缺失:输入范围错误后,打印提示但没有重新引导输入的语句,下一次循环直接开始读取输入,用户体验极差;且break后未重置flag,导致循环逻辑混乱。
修复后的函数:
void enterRow(int numbers[], int len, int maxValue) { int flag; do { flag = 0; // 每次循环重置flag:0表示输入合法,1表示非法 printf("\nEnter your lotto row (%d values between 1-%d): ", len, maxValue); // 读取所有输入 for(int i = 0; i < len; i++) { scanf(" %d", &numbers[i]); } // 逐个校验输入合法性 for (int i = 0; i < len; i++) { // 校验数值范围 if (numbers[i] < 1 || numbers[i] > maxValue) { printf("Numbers must be between 1-%d, try again!\n", maxValue); flag = 1; break; } // 校验是否重复(传入当前索引,只对比前面的元素) if (checkIfContains(numbers[i], numbers, len, i)) { printf("Duplicate found, try again!\n"); flag = 1; break; } } } while (flag == 1); }
3. 次要优化点
- 原代码中
int numbers[len];是变长数组(VLA),C99支持但部分老编译器可能需要开启选项,若兼容性有问题,可改为固定大小int numbers[7];或动态分配内存。 - 初始化时的
memset(numbers, 0, sizeof(int) * len);完全多余,因为每次输入都会覆盖数组元素,可直接删除。
内容的提问来源于stack exchange,提问作者dynamitri
相关产品推荐
相关产品推荐

