c - 为什么我的 PSET1 Credit 可以在沙盒中运行,但不能在 Check50 中运行?

标签 c cs50 luhn

我遇到问题,我的 PSET1 信用程序在 CS50 沙盒中运行,并且能够根据卡的长度和 Luhn 算法确定卡是 MasterCard、AMEX 还是 VISA。但是,当我将代码提交给 Check50 时,它确定所有输入都是无效的。

更新:如果数字不符合 Luhn 算法,我不会打印“INVALID”,而是将其更改为打印“nope”,并发现 check50 检查的所有数字都会导致输出“nope”,所以我知道该错误位于程序的该部分中的某个位置。和以前一样,它仍然可以在沙箱中运行。

我在这里和其他地方寻找过类似的问题和解决方案。

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

int main(void)
{
    //Ask user to input number.
    long card_num;
    do
    {
        card_num = get_long("Number: ");   
    }
    //Check if card number is greater than zero.
    while (card_num < 0);

    //Starting with the second to last digit, multiply each digit by 2.
    //Add the products' digits together.
    int digit, prod, sum1, dig1, dig2;
    long holder = card_num;
    while (holder > 0)
    {
        digit = (holder / 10) % 10;
        prod = digit * 2;
        if (prod >= 10)
        {
            dig1 = (prod % 100 - (prod % 10)) / 10;
            dig2 = prod % 10;
            prod = dig1 + dig2;
        }
        sum1 = sum1 + prod;
        holder = holder / 100;
    }

    //Add sum1 to product of the other digits in the card number
    long holder1 = card_num;
    int dig3, sum2;
    while (holder1 > 0)
    {
        dig3 = holder1 % 10;
        sum2 = sum2 + dig3;
        holder1 = holder1 / 100;
    }

    //Check if the sum of the first and second sums has a final digit of 0.
    int last_sum = sum1 + sum2;
    if (last_sum % 10 != 0)
    {
        printf("INVALID\n");
    }
    else
    {
        //Calculate number of digits
    int num_digits = 0;
    long holder3 = card_num;
    while (holder3 != 0)
    {
        holder3 = holder3 / 10;
        num_digits++;
    }

    //Find first two digits of card number
    long holder2 = card_num;
    while (holder2 > 100)
    {
         holder2 = holder2 / 10;
    }
    int firstdig, secdig;
    secdig = holder2 % 10;
    firstdig = holder2 / 10;

    //Check if VISA, Mastercard, or AMEX
    if (firstdig == 4)
    {
        if (num_digits == 13 || num_digits == 16)
        {
            printf ("VISA\n");
        }
    }
    else if (firstdig == 5 && secdig >= 1 && secdig <= 5)
    {
        if (num_digits == 16)
        {
            printf ("MASTERCARD\n");
        }
    }
    else if (firstdig == 3 && (secdig == 4 || secdig == 7))
    {
        if (num_digits == 15)
        {
            printf ("AMEX\n");
        }
    }
    else (printf("INVALID\n"));
    }
}

预期结果为 MASTERCARD、VISA、AMEX 或 INVALID。在沙盒中它可以工作,但 Check50 对所有数字都无效。

最佳答案

不同的系统可以对“long”的大小有不同的实现。

建议使用 stdint.h 中的 uint64_t 因为

  1. 在不同的系统/实现中始终具有相同的大小
  2. 该值需要无符号,因为移动有符号值会出现问题。

调用scanf()时,建议使用格式说明符:SCNu64

SCNu64 来自 inttypes.h

scanf() 的示例

uint64_t card_num;
scanf( "%" SCNu64, &card_num );
<小时/>

how to validate a credit card number

记下信用卡号的最后一位数字。这是您将用来验证信用卡号其余部分的校验和数字。

列出信用卡号的每一位数字,从校验和左侧的数字开始并向左移动。如果信用卡号有 16 位数字,请将奇数位置的每个数字的金额加倍(从右到左),然后再将其添加到列表中。对于 15 位数字的信用卡,您可以将偶数位置的数字加倍。如果将一位数字加倍后得到的数字大于 10,请将新数字的两位数字相加并将结果写在您的列表中。例如,如果卡上的数字是 7,则将其加倍将得到 14。这两个数字的总和将是 5。

合计您的数字列表。不要将校验和数字包含在总数中。如果总数能被10整除,则该信用卡的号码有效。如果不是,您不应处理信用卡交易。

<小时/>

How to determine supplier of credit card

通过查看第一个数字来识别银行卡的信用卡公司。以“3”开头的卡是美国运通卡。以“4”开头的是 Visa 信用卡和借记卡,以“5”开头的是 MasterCard 信用卡和借记卡,以“6”开头的是 Discover 信用卡。向商户收取的服务费因卡公司而异。

计算信用卡号码中的数字。大多数信用卡应包含 15 或 16 位数字。美国运通信用卡包含 15 位数字。其他三大信用卡公司——Visa、Mastercard 和 Discover——其卡上有 16 位数字序列。

关于c - 为什么我的 PSET1 Credit 可以在沙盒中运行,但不能在 Check50 中运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58050920/

相关文章:

c++ - 我应该如何处理信用卡号验证算法?

c - 验证卡信用号码

python - Luhn 算法在 (I)python 中的意外表现

c - 不使用 [ 或 ] 查找数组中元素的总和

c - C(ubuntu)中的Makefile多重定义

c - Vigenere Cipher - 如何忽略纯文本中的空格(在 C 中)?

CS50 维吉尼亚密码给出错误的输出

c - 从字节的 char[] 中获取 int

c - 为什么我得到 24 作为此代码的输出

c - 让贪婪算法适用于每个输入