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

CS50信用卡验证代码部分卡号无法运行问题求助

CS50信用卡验证代码问题排查与修复

你的代码存在多个导致部分卡号验证失败的问题,以下是具体问题和修复方案:

核心问题分析

1. 未声明变量引发的未定义行为

  • main函数中的valid、length、digits、digit_visa未声明,check_sum函数中的sec_to_last、double_sec_to_last、first_dig、sec_dig、first_sum、second_sum也未声明。这些未定义的变量会随机取值,直接导致校验逻辑混乱。

2. 参数类型不匹配

  • check_sum的参数是int类型,但传入的是long类型的卡号。当卡号数值超过int的范围(大于2147483647)时,会发生数值截断,导致校验完全错误。

3. Luhn校验算法逻辑错误

  • check_sum的第二个循环while (num2 >= 10)中,num2未做除法操作,会陷入无限循环;同时算法本身没有正确实现Luhn规则:未按要求从右往左交替处理数字,而是错误地截取两位数操作。

4. 数据类型范围不足

  • 32位long类型的最大值为2147483647,无法存储部分16位信用卡卡号(如4999999999999999),必须使用long long类型才能覆盖所有合法卡号。

5. 长度计算的浮点误差

  • 使用floor(log10(labs(num))) + 1计算卡号长度时,浮点运算可能存在精度误差,导致长度判断错误,改用循环计数更可靠。

修复后的完整代码

#include <stdio.h>
#include <cs50.h>

bool check_sum(long long num);
int check_length(long long num);
long long get_first_digits(long long num);
long long get_cc_number(void);

int main(void)
{
    // 获取信用卡卡号
    long long num = get_cc_number();

    // 校验Luhn规则
    bool valid = check_sum(num);

    // 获取卡号长度
    int length = check_length(num);

    // 获取前两位数字(用于判断卡组织)
    long long digits = get_first_digits(num);
    int digit_visa = digits / 10;

    // 判断卡组织
    if (valid)
    {
        if (length == 16)
        {
            if (digits >= 51 && digits <= 55)
            {
                printf("MASTERCARD\n");
            }
            else if (digit_visa == 4)
            {
                printf("VISA\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
        else if (length == 15)
        {
            if (digits == 34 || digits == 37)
            {
                printf("AMEX\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
        else if (length == 13)
        {
            if (digit_visa == 4)
            {
                printf("VISA\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
        else
        {
            printf("INVALID\n");
        }
    }
    else
    {
        printf("INVALID\n");
    }
}

long long get_cc_number(void)
{
    long long cc_number;
    cc_number = get_long("Credit Card Number: ");
    return cc_number;
}

bool check_sum(long long num)
{
    int sum = 0;
    bool alternate = false;

    while (num > 0)
    {
        int digit = num % 10;
        // 从右往左交替乘以2
        if (alternate)
        {
            digit *= 2;
            // 拆分两位数求和
            sum += digit / 10 + digit % 10;
        }
        else
        {
            sum += digit;
        }
        alternate = !alternate;
        num /= 10;
    }
    return sum % 10 == 0;
}

int check_length(long long num)
{
    int length = 0;
    while (num > 0)
    {
        length++;
        num /= 10;
    }
    return length;
}

long long get_first_digits(long long num)
{
    while (num >= 100)
    {
        num /= 10;
    }
    return num;
}

修复说明

  • 所有涉及卡号的变量统一改为long long类型,避免数值溢出;
  • 修正Luhn校验算法,按标准规则从右往左交替处理数字;
  • 改用循环计数计算卡号长度,消除浮点误差;
  • 补全所有变量声明,避免未定义行为;
  • 调整main函数中的分支逻辑,增加对非法长度的直接判断。

内容的提问来源于stack exchange,提问作者antoniomcoelho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:27:15