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

为何checkCS50判定我的pset1 credit代码未完全通过测试?

CS50 Pset1 Credit作业验证异常问题

我的Credit作业代码部分信用卡号码验证符合预期,但部分未通过checkCS50检测,被判定为INVALID而非正确卡种,具体检测结果如下:

:) credit.c exists

:) credit.c compiles

:( identifies 378282246310005 as AMEX
    expected "AMEX\n", not "INVALID\n"

:( identifies 371449635398431 as AMEX
    expected "AMEX\n", not "INVALID\n"

:( identifies 5555555555554444 as MASTERCARD
    expected "MASTERCARD\n", not "INVALID\n"

:( identifies 5105105105105100 as MASTERCARD
    expected "MASTERCARD\n", not "INVALID\n"

:) identifies 4111111111111111 as VISA

:( identifies 4012888888881881 as VISA
    expected "VISA\n", not "INVALID\n"

:) identifies 4222222222222 as VISA

:) identifies 1234567890 as INVALID (invalid length, checksum, identifying digits)

:) identifies 369421438430814 as INVALID (invalid identifying digits)

:) identifies 4062901840 as INVALID (invalid length)

:) identifies 5673598276138003 as INVALID (invalid identifying digits)

:) identifies 4111111111111113 as INVALID (invalid checksum)

:) identifies 4222222222223 as INVALID (invalid checksum)

:) identifies 3400000000000620 as INVALID (AMEX identifying digits, VISA/Mastercard length)

:) identifies 430000000000000 as INVALID (VISA identifying digits, AMEX length)

我的代码如下:

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

int main(void)
{
long creditLong = get_long("What is your credit card number? "); // Get the number
char creditArray[20]; // Convert to array
snprintf(creditArray, sizeof(creditArray), "%ld", creditLong);

long creditLength = strlen(creditArray); // Get length
// printf("creditLength is %ld\n", creditLength);

int sumFirst = 0; // Checksum variables
int sumSecond = 0;

for (int i = creditLength - 2; i >= 0; i -= 2)
{                                     // For loops to get sum
    int digit = creditArray[i] - '0'; // ASCII to Int value ('0' = 48 in ASCII)
    sumFirst += digit * 2;
}

for (int j = creditLength - 1; j >= 0; j -= 2)
{
    int digit = creditArray[j] - '0';
    sumSecond += digit;
}
int checkSum = sumFirst + sumSecond;


char luhnTest[10]; // Convert to array
snprintf(luhnTest, sizeof(luhnTest), "%d", checkSum);
int testLength = strlen(luhnTest); // Get length of card number

if (luhnTest[testLength - 1] == '0')
{ // Start of If Statement

    switch (creditLength)
    {
        case 15:
            if (creditArray[0] == '3' && (creditArray[1] == '4' || creditArray[1] == '7'))
            {
                printf("AMEX\n");
            }
            else
            {
                printf("INVALID\n");
            }
            break;

        case 13:
            if (creditArray[0] == '4')
            {
                printf("VISA\n");
            }
            else
            {
                printf("INVALID\n");
            }
            break;

        case 16:
            if (creditArray[0] == '4')
            {
                printf("VISA\n");
            }
            else if (creditArray[0] == '5' && (creditArray[1] == '1' || creditArray[1] == '2' || creditArray[1] == '3' ||
                                               creditArray[1] == '4' || creditArray[1] == '5'))
            {
                printf("MASTERCARD\n");
            }
            else
            {
                printf("INVALID\n");
            }
            break;

        default:
            printf("INVALID\n");
    }
} // End of IF Statement
else
{
    printf("INVALID\n");
}
}

问题原因

核心错误出在Luhn算法的实现上:按照规则,需要将从右数第二位开始的数字乘2,然后把乘积的每一位数字相加,而非直接将乘积本身加入sumFirst。比如数字8乘2得16,应该加1+6=7,而代码里直接加了16,导致checksum计算错误,最终这些测试用例的Luhn验证不通过,返回INVALID。

修正后的代码

将sumFirst的计算逻辑修改为拆分乘积的各位数字相加,同时优化了checksum的验证方式:

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

int main(void)
{
long creditLong = get_long("What is your credit card number? ");
char creditArray[20];
snprintf(creditArray, sizeof(creditArray), "%ld", creditLong);

long creditLength = strlen(creditArray);

int sumFirst = 0;
int sumSecond = 0;

for (int i = creditLength - 2; i >= 0; i -= 2)
{
    int digit = creditArray[i] - '0';
    int product = digit * 2;
    // 拆分乘积的各位数字相加
    sumFirst += (product / 10) + (product % 10);
}

for (int j = creditLength - 1; j >= 0; j -= 2)
{
    int digit = creditArray[j] - '0';
    sumSecond += digit;
}
int checkSum = sumFirst + sumSecond;

// 直接判断checkSum是否能被10整除,无需转字符串
if (checkSum % 10 == 0)
{
    switch (creditLength)
    {
        case 15:
            if (creditArray[0] == '3' && (creditArray[1] == '4' || creditArray[1] == '7'))
            {
                printf("AMEX\n");
            }
            else
            {
                printf("INVALID\n");
            }
            break;

        case 13:
            if (creditArray[0] == '4')
            {
                printf("VISA\n");
            }
            else
            {
                printf("INVALID\n");
            }
            break;

        case 16:
            if (creditArray[0] == '4')
            {
                printf("VISA\n");
            }
            else if (creditArray[0] == '5' && (creditArray[1] >= '1' && creditArray[1] <= '5'))
            {
                printf("MASTERCARD\n");
            }
            else
            {
                printf("INVALID\n");
            }
            break;

        default:
            printf("INVALID\n");
    }
}
else
{
    printf("INVALID\n");
}
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:54:55