C语言代码if条件异常:合法字符被判定为非法问题求助
代码功能说明
接收一个“酷字母”(如b),再接收一段文本(如bhkb kBfj),扫描文本中的目标字母(b/B):
- 每匹配一个字母得1分
- 连续匹配额外加1分
异常现象
输入合法的英文字母和空格时,if (check_letter_validity(x)==false)条件被触发,score被设为-1。例如输入酷字母b、文本bhkb kBfj时,预期得分为2,实际输出score为-1。
问题代码
#include <stdbool.h> //functions bool check_letter_validity(char); int main() { int score=0; char c=0,x=0,previous_value=0; printf("Please Enter Cool Letter :\n"); scanf(" %c", &c); printf("Please Enter Text :\n"); while (scanf(" %c", &x) == 1 ){ if (check_letter_validity(x)==false) { score = -1; break; } if (x == c || x == c-('a'-'A')){ score++; if (previous_value == c || previous_value == c-('a'-'A')) score++; } previous_value = x; } printf("The score is: %d", score); return 0; } bool check_letter_validity(char x){ if (x==' ') return true; if (x<='z' && x>='a') return true; if (x>='A' && x<='Z') return true; else return false; }
原因分析及修复方案
核心原因1:scanf跳过空白字符+全角空格未被识别
代码中scanf(" %c", &x)的格式符前带有空格,会让scanf自动跳过所有标准空白字符(半角空格、换行、制表符等),因此文本中的半角空格不会被读入x;但如果输入了全角空格(ASCII值12288),它不属于标准空白字符,会被读入x,而check_letter_validity只判断半角空格(ASCII 32),因此会返回false,触发score=-1。
核心原因2:大小写转换逻辑存在隐患
当输入的酷字母是大写时,c-('a'-'A')会计算出非字母字符(例如大写'A'是65,65-32=33,对应感叹号!),虽然不是当前异常的直接原因,但会导致后续匹配逻辑错误。
修复方案
兼容全角空格或规范输入:
如果需要支持全角空格,在check_letter_validity中添加判断:if (x == 12288) return true; // 匹配全角空格或者提示用户仅输入半角空格。
修正
scanf读取逻辑,保留空格:
若需要读取文本中的空格,将scanf(" %c", &x)改为scanf("%c", &x)(去掉前面的空格),同时处理换行符:while (scanf("%c", &x) == 1 && x != '\n'){ // 原有逻辑 }更可靠的方式是用
fgets读取整行文本后逐个处理:#include <string.h> // ... char text[1000]; // 跳过酷字母输入后的残留换行 getchar(); printf("Please Enter Text :\n"); fgets(text, sizeof(text), stdin); for (int i=0; text[i] != '\0' && text[i] != '\n'; i++){ char x = text[i]; // 原有检查、计分逻辑 }用标准库函数修正大小写转换:
使用toupper/tolower统一大小写,避免手动计算出错:#include <ctype.h> // ... if (toupper(x) == toupper(c)){ score++; if (toupper(previous_value) == toupper(c)) score++; }
内容的提问来源于stack exchange,提问作者Razi Al Ashhab

