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

CS50 credit.c信用卡验证程序两个无效卡号误识别为VISA问题

问题描述

我目前遇到的错误集中在数学计算逻辑部分,所有尝试的修改方案都没有生效。

附:抱歉问题格式不够规范,这是我第一次使用Stack Overflow。

测试用例运行结果如下:

  • :) credit.c 存在
  • :) credit.c 编译通过
  • :) 识别378282246310005为AMEX
  • :) 识别371449635398431为AMEX
  • :) 识别5555555555554444为MASTERCARD
  • :) 识别5105105105105100为MASTERCARD
  • :) 识别4111111111111111为VISA
  • :) 识别4012888888881881为VISA
  • :) 识别4222222222222为VISA
  • :) 识别1234567890为INVALID
  • :) 识别369421438430814为INVALID
  • :) 识别4062901840为INVALID
  • :) 识别5673598276138003为INVALID
  • :( 识别4111111111111113为INVALID,预期输出"INVALID\n",实际输出"VISA\n"
  • :( 识别4222222222223为INVALID,预期输出"INVALID\n",实际输出"VISA\n"

原代码如下:

#include <cs50.h>
#include <math.h>

// 提示用户输入信用卡号
int main(void)
{
    long credit_card, credit_number;
    do
    {
        credit_card = get_long("Enter credit card number: ");
    }
    while (credit_card < 0);
    
    credit_number = credit_card;
    
    // 计算总位数
    int count = (credit_number == 0) ? 1  : (log10(credit_number) + 1);
    int summation = 0;

    while (credit_number == 0)
    {
        int x = credit_number % 10; summation += x;
        int y = 2 * ((credit_number / 10) % 10);
        int r = (y % 10) + floor((y / 10) % 10); summation += r; credit_number /= 100;
    }

    string card;
    // 识别输入的信用卡号对应的卡类型
    int test = cc / pow(10, count - 2);
    if ((count == 13 || count == 16) && test / 10 == 4)
    {
        card = "VISA";
    }
    else if (count == 16  && test >= 51 && test <= 55)
    {
        card = "MASTERCARD";
    }
    else if (count == 15 && (test == 34 || test == 37))
    {
        card = "AMEX";
    }
    else
    {
        card = "INVALID";
    }

    // 最终校验
    if (sum % 10 == 0)
    {
        printf("%s\n", card);
    }
    else
    {
        printf("INVALID\n");
    }
}
问题原因
  1. Luhn算法的循环条件错误:你写的while (credit_number == 0)永远不会触发循环,求和变量summation始终为0,最终校验sum%10==0永远成立,只要卡号开头符合卡种规则就会直接输出卡种,跳过了校验逻辑,这是两个失败用例的核心原因。
  2. 变量名未定义/不匹配:计算卡号前缀时使用的cc未定义,应该替换为存储原始卡号的credit_card;最终校验时使用的sum也未定义,应该替换为你定义的求和变量summation。
  3. 浮点数精度问题:使用log10、pow这类浮点运算函数处理整数逻辑,大概率会出现精度误差,建议改用纯整数运算计算位数和卡号前缀。
修改后的完整代码
#include <cs50.h>
#include <stdio.h>

int main(void)
{
    long credit_card, credit_number;
    do
    {
        credit_card = get_long("Enter credit card number: ");
    }
    while (credit_card < 0);
    
    credit_number = credit_card;
    
    // 整数运算计算总位数,避免浮点精度问题
    int count = 0;
    long temp = credit_card;
    while (temp > 0)
    {
        temp /= 10;
        count++;
    }
    int summation = 0;
    temp = credit_number;

    // 修正循环条件,正确执行Luhn算法
    while (temp > 0)
    {
        int x = temp % 10;
        summation += x;
        temp /= 10;
        if (temp == 0) break;
        int y = 2 * (temp % 10);
        summation += (y % 10) + (y / 10);
        temp /= 10;
    }

    // 整数运算计算卡号前两位
    long prefix = credit_card;
    while (prefix >= 100)
    {
        prefix /= 10;
    }

    string card = "INVALID";
    // 识别卡类型
    if ((count == 13 || count == 16) && prefix / 10 == 4)
    {
        card = "VISA";
    }
    else if (count == 16  && prefix >= 51 && prefix <= 55)
    {
        card = "MASTERCARD";
    }
    else if (count == 15 && (prefix == 34 || prefix == 37))
    {
        card = "AMEX";
    }

    // 修正变量名,执行最终校验输出
    if (summation % 10 == 0)
    {
        printf("%s\n", card);
    }
    else
    {
        printf("INVALID\n");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:18:02