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

CS50课程:C语言信用卡验证程序故障排查与优化求助

解决CS50信用卡验证程序的无输出问题

你的程序目前存在逻辑漏洞:当卡号通过了长度校验和Luhn算法校验,但不属于Visa、American Express、MasterCard这三类时,没有任何输出语句被触发。因为现有代码里,INVALID只在长度不合法或Luhn校验失败时输出,而卡种匹配的if都是独立判断,不匹配就不会执行任何输出操作。

修复思路

引入一个状态变量跟踪卡的有效性,默认标记为无效,只有当卡号通过所有校验且匹配指定卡种时,才更新状态为对应卡种,最后统一输出结果,确保所有场景都有明确输出。

修改后的完整代码

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

// AMEX 34, 37; MASTERCARD 51-55; VISA 4
// 合法长度:13, 15, 16 位
int main(void)
{
    long long number = get_long("Credit Card Number: ");
    long long cc = number;
    int length = 0;
    char status = 'I'; // 默认标记为无效(Invalid)

    // 计算卡号长度
    while (cc > 0)
    {
        cc /= 10;
        length++;
    }

    // 提取前两位和第一位数字
    long long cc1 = number;
    for (int x = 0; x < length - 2; x++)
    {
        cc1 /= 10;
    }
    int firsttwo = cc1;
    int first = cc1 / 10;

    // Luhn算法校验
    long long i = number;
    int d;
    int sum = 0;
    while (i > 0)
    {
        d = i % 10;
        sum += d;
        i /= 100;
    }

    long long y = number / 10;
    int d2;
    int prod = 0;
    int sum2 = 0;
    while (y > 0)
    {
        d2 = y % 10;
        prod = d2 * 2;
        if (prod >= 10)
        {
            prod = prod - 9;
        }
        sum2 += prod;
        y /= 100;
    }

    int total = sum + sum2;

    // 仅当长度合法且Luhn校验通过时,才判断卡种
    if ((length == 13 || length == 15 || length == 16) && (total % 10 == 0))
    {
        if ((length == 13 || length == 16) && first == 4)
        {
            status = 'V'; // Visa
        }
        else if (length == 15 && (firsttwo == 34 || firsttwo == 37))
        {
            status = 'A'; // American Express
        }
        else if (length == 16 && (firsttwo >= 51 && firsttwo <= 55))
        {
            status = 'M'; // MasterCard
        }
        // 不匹配以上卡种时,status保持'I'
    }

    // 统一输出结果
    switch(status)
    {
        case 'V':
            printf("VISA\n");
            break;
        case 'A':
            printf("AMEX\n");
            break;
        case 'M':
            printf("MASTERCARD\n");
            break;
        default:
            printf("INVALID\n");
            break;
    }
}

关键修改点

  1. 将所有存储卡号的long类型改为long long,避免16位卡号超出32位整数范围导致溢出。
  2. 新增status变量统一管理输出状态,覆盖「长度非法」「Luhn校验失败」「卡种不匹配」等所有无效场景。
  3. 将卡种判断嵌套在「长度合法+Luhn校验通过」的大条件中,逻辑更严谨——只有基础校验通过,才需要判断卡种。
  4. 用else if替代独立if,避免逻辑冗余,同时保证同一卡号只匹配一种卡种。
  5. 通过switch统一输出,确保无论什么情况都有明确的输出结果。

内容的提问来源于stack exchange,提问作者noah-jawn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:45:29