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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:01:00