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

CS50信用卡校验代码中else if分支失效问题求助

哈佛CS50信用卡验证程序卡种识别故障排查

我为哈佛CS50课程编写了信用卡号码验证程序,流程为:获取卡号 → 验证位数合法性 → 通过校验和判断有效性 → 识别卡种。目前校验和功能正常,但卡种识别逻辑存在问题:当卡号首数字为3、次数字为7(符合AMEX卡规则)时,程序无法正确识别,始终返回INVALID。请问这部分的else if分支为何无法正常工作?

问题代码

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

long get_number(void);
int get_digits(long creditnumber);
int calcfirst(long creditnumber);
bool checksum(long creditnumber, int digits);

int main(void)
{
    long creditnumber = get_number();
    int digits = get_digits(creditnumber);
    int firstdigit = calcfirst(creditnumber);
    int seconddigit = calcfirst(creditnumber);

    if (digits != 13 && digits != 15 && digits != 16)
    {
        printf("INVALID\n");
    }
    else
    {
        if (checksum(creditnumber, digits))
        {
            if (firstdigit == 4)
            {
                printf("VISA\n");
            }
            else if (firstdigit == 5 && (seconddigit > 0 && seconddigit < 6))
            {
                printf("MASTERCARD\n");
            }
            else if (firstdigit == 3 && (seconddigit == 4 || seconddigit == 7))
            {
                printf("AMEX\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
        else
        {
            printf("INVALID\n");
        }
    }
    return 0;
}

long get_number(void)
{
     long creditnumber = get_long("Number: ");
     return creditnumber;
}

int get_digits(long creditnumber)
{
    int digits = 0;
    do
    {
        creditnumber /= 10;
        digits++;
    }
    while (creditnumber != 0);

    return digits;
}

int calcfirst(long creditnumber)
{
    int firstdigit;
    int seconddigit;
    int firstnum;

    long n = creditnumber;
    while (n > 100)
    {
        n /= 10;
    }
    firstnum = n;

    firstdigit = firstnum / 10;
    seconddigit = firstnum % 10;

    return firstdigit;
    return seconddigit;
}

故障原因

核心问题出在calcfirst函数的返回逻辑:

  • 函数中连续写了两个return语句:return firstdigit;执行后,程序会立即退出函数,后续的return seconddigit;永远不会被执行。
  • 在main函数中,firstdigit和seconddigit都是通过调用calcfirst(creditnumber)赋值的,因此两者拿到的都是第一位数字,而非预期的第一位和第二位。
  • 以AMEX卡为例,卡号首数字是3,此时seconddigit的值也是3,自然无法满足seconddigit ==4 || seconddigit ==7的判断条件,导致分支失效。

修复方案

方案一:用指针传递获取两位数字

修改calcfirst函数,通过指针参数同时返回第一位和第二位数字,避免重复计算:

void calcfirst(long creditnumber, int *firstdigit, int *seconddigit)
{
    long n = creditnumber;
    while (n > 100)
    {
        n /= 10;
    }
    int firstnum = n;
    *firstdigit = firstnum / 10;
    *seconddigit = firstnum % 10;
}

然后在main函数中调整调用方式:

int firstdigit, seconddigit;
calcfirst(creditnumber, &firstdigit, &seconddigit);

方案二:拆分函数分别获取

如果不想用指针,可以拆分为两个独立函数:

int getFirstDigit(long creditnumber)
{
    long n = creditnumber;
    while (n >= 10)
    {
        n /= 10;
    }
    return n;
}

int getSecondDigit(long creditnumber)
{
    long n = creditnumber;
    while (n >= 100)
    {
        n /= 10;
    }
    return n % 10;
}

在main函数中分别调用:

int firstdigit = getFirstDigit(creditnumber);
int seconddigit = getSecondDigit(creditnumber);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 06:24:17