C语言输入验证逻辑异常:break语句无效,错误提示不符预期
输入验证功能BUG排查与修复
问题现象
输入不足6位数字(比如"123")时,本该提示需补充对应位数,却始终触发"ERROR: A character in your guess was not a digit or a white space"错误;无论输入内容如何,都会触发该错误提示,无法正常进行位数验证。
核心问题分析
- 字符串越界访问触发误判:第一个验证循环固定遍历前6个字符,当输入长度不足6时,
input[i]会访问到字符串结束符\0,而isdigit('\0')返回false,直接触发非数字错误。 - 条件判断逻辑完全颠倒:第二个循环里的
isdigit(input[i] == 1)是把input[i] == 1的布尔值(0或1)传给isdigit,完全偏离了判断字符是否为数字的逻辑;而且remainder = 6 - numCount在numCount统计前就计算,结果永远是6,完全错误。 - 状态变量管理混乱:
error、enoughDigits每次循环没有重置,错误状态会累积;输入验证不通过时,匹配逻辑依然执行,会访问未初始化的guessArray,导致不可预料的行为。 - 未实现空格忽略需求:
scanf("%s")遇到空格就停止读取,根本没处理题目要求的"忽略空格或制表符"的规则。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> int main() { int solutionArray[6]; int guessArray[6]; // 生成随机数序列 int seed; printf("Enter the integer value of the seed for the game: "); scanf("%d", &seed); srand(seed); for(int i = 0; i < 6; i++){ solutionArray[i] = rand() % 10; printf("%3d", solutionArray[i]); } printf("\n"); // 游戏说明 printf("For each turn enter 6 digits 0 <= digit <= 9 \n"); printf("Spaces or tabs in your response will be ignored. \n"); char input[100]; int error; int enoughDigits; do { // 每次循环重置状态变量 error = 0; enoughDigits = 0; int numCount = 0; char filteredInput[10] = {0}; // 存储过滤后的数字 printf("Enter your guess, 6 digits: "); // 用fgets读取整行,处理空格 fgets(input, sizeof(input), stdin); // 跳过scanf遗留的换行符(第一次循环时) if (input[0] == '\n') { fgets(input, sizeof(input), stdin); } // 过滤输入:保留数字,忽略空格、制表符,其他字符直接报错 for (int i = 0; input[i] != '\0'; i++) { if (isspace(input[i])) { continue; // 忽略空格和制表符 } else if (isdigit(input[i])) { if (numCount < 6) { // 最多保留6个数字 filteredInput[numCount++] = input[i]; } } else { printf("ERROR: A character in your guess was not a digit or a white space\n\n"); error = 1; break; } } // 验证数字数量 if (!error) { if (numCount < 6) { int remainder = 6 - numCount; printf("You need to enter %d more digits to complete your guess \n\n", remainder); enoughDigits = 1; } else { // 转换为数字数组 for (int i = 0; i < 6; i++) { guessArray[i] = filteredInput[i] - '0'; } // 输出用户猜测 printf("Your guess was:\n"); for (int i = 0; i < 6; i++) { printf("%2d", guessArray[i]); } printf("\n"); // 计算匹配结果 int partialMatches = 0; int perfectMatches = 0; // 标记已匹配的位置,避免重复计算 int usedSolution[6] = {0}; int usedGuess[6] = {0}; // 先统计完全匹配 for (int i = 0; i < 6; i++) { if (solutionArray[i] == guessArray[i]) { perfectMatches++; usedSolution[i] = 1; usedGuess[i] = 1; } } // 统计部分匹配 for (int i = 0; i < 6; i++) { if (usedSolution[i]) continue; for (int j = 0; j < 6; j++) { if (!usedGuess[j] && solutionArray[i] == guessArray[j]) { partialMatches++; usedSolution[i] = 1; usedGuess[j] = 1; break; } } } // 输出结果 printf("%d perfect matches, %d partial matches\n", perfectMatches, partialMatches); if (perfectMatches == 6) { printf("YOU DID IT!\n"); break; } } } } while (error == 1 || enoughDigits == 1); return 0; }
关键修复点说明
- 输入读取优化:改用
fgets读取整行输入,解决scanf无法处理空格的问题;同时处理第一次循环时scanf遗留的换行符,避免直接跳过输入。 - 输入过滤逻辑:遍历输入字符,忽略空格/制表符,遇到非数字直接报错,有效数字存入临时数组,最多保留6个。
- 验证逻辑调整:先过滤再统计数字数量,避免越界访问;只有在无错误且数字足够时,才执行匹配计算。
- 状态变量重置:每次循环开始时重置
error、enoughDigits等变量,避免上一次的错误状态影响当前循环。 - 匹配逻辑修正:新增
usedSolution和usedGuess数组标记已匹配的位置,解决原代码中部分匹配计算重复的问题。
内容的提问来源于stack exchange,提问作者waystarmardco
相关产品推荐
相关产品推荐

