VIN验证函数失效排查求助:原正常函数现误返回true
VIN验证函数错误排查求助
我编写了一段C++代码,实现车辆识别码(VIN)的三个功能:验证合法性、查询生产地、获取生产年份。原本valid函数可以正常工作,但完成origin和year函数后,测试时发现valid函数在不符合验证规则的情况下仍会返回true。
VIN的验证规则:
- 长度必须为17位
- 仅包含数字和大写字母
- 禁止使用字母I、O、Q、U、Z
我尝试重写valid函数,但只有长度判断和循环结构能正常工作,无法定位具体问题,恳请帮忙排查错误。
编辑说明:已为VIN数组补充缺失的一位数字。
我的代码
using namespace std; #include <cstring> #include<cctype> #include <iostream> #pragma warning(disable : 4996) bool valid(char[]); void origin(char[], char[]); int year(char[]); int main() { bool validity; char vin[] = "1FTRW14W84KC76110"; char country[20]; cout << "Testing the VIN " << vin << endl; validity = valid(vin); if (validity == true) { cout << "\nVIN is valid" << endl; } else { cout << "\nVIN is not vaild." << endl; } origin(vin, country); cout << "Year: " << year(vin) << endl; return 0; } bool valid(char vin[]) { bool result = false; long long length = strlen(vin); if (length == 17) { for (int i = 0; i < 17; i++) { if (isalnum(vin[i])) { if (isupper(vin[i])) { if (vin[i] != 'I' && vin[i] != 'O' && vin[i] != 'Q' && vin[i] != 'U' && vin[i] != 'Z') { return true; } else { return false; } } else if (isdigit(vin[i])) { return true; } else { return false; } } else { return false; } } } else { result = false; } return result; } void origin(char vin[], char country[]) { if (vin[0] >= 'A' && vin[0] <= 'H') { strcpy(country, "Africa"); cout << "Origin: " << country << endl; } else if (vin[0] >= 'J' && vin[0] <= 'R') { strcpy(country, "Asia"); cout << "Origin: " << country << endl; } else if (vin[0] >= 'S' && vin[0] <= 'Y') { strcpy(country, "Europe"); cout << "Origin: " << country << endl; } else if (vin[0] >= '1' && vin[0] <= '5') { strcpy(country, "North America"); cout << "Origin: " << country << endl; } else if (vin[0] >= '6' && vin[0] <= '7') { strcpy(country, "Oceania"); cout << "Origin: " << country << endl; } else { strcpy(country, "South America"); cout << "Origin: " << country << endl; } } int year(char vin[]) { int y; if (isdigit(vin[9])){ y = 2000 + (vin[9] - '0'); } if (vin[9] <= 'M') { y = 2010 + (vin[9] - 'A'); } else{ y = 1993 + (vin[9] - 'P'); } return y; }
问题分析与修正
1. valid函数的核心错误
你的valid函数在循环检查第一个符合要求的字符时就直接返回true,完全没有检查后续的16位字符。比如只要第一个字符是合法的数字或大写字母,函数就直接返回true,后面哪怕有非法字符也不会被检测到。
正确的逻辑应该是:遍历所有字符,只要发现一个非法字符就立即返回false;只有所有字符都通过检查后,才返回true。
修正后的valid函数:
bool valid(char vin[]) { // 先检查长度 if (strlen(vin) != 17) { return false; } for (int i = 0; i < 17; i++) { char c = vin[i]; // 检查是否是数字或字母 if (!isalnum(c)) { return false; } // 如果是大写字母,检查是否在禁用列表中 if (isupper(c)) { if (c == 'I' || c == 'O' || c == 'Q' || c == 'U' || c == 'Z') { return false; } } // 如果是小写字母,直接判定非法(规则要求大写) else if (islower(c)) { return false; } // 数字无需额外检查,已通过isalnum验证 } // 所有检查通过 return true; }
2. year函数的潜在问题
你的year函数里三个if是独立执行的,没有使用else if,会导致赋值被覆盖。比如当vin[9]是数字时,第一个if给y赋值后,后面的if依然会执行并重新赋值,导致结果错误。
修正后的year函数:
int year(char vin[]) { int y; char c = vin[9]; if (isdigit(c)){ y = 2000 + (c - '0'); } else if (c <= 'M') { y = 2010 + (c - 'A'); } else{ y = 1993 + (c - 'P'); } return y; }
内容的提问来源于stack exchange,提问作者user20078963
相关产品推荐
相关产品推荐

