为什么我的PSET1积分不能在沙箱中使用,而Check50却不能?

时间:2019-09-22 15:55:05

标签: c cs50

我遇到了一个问题,即我的PSET1信用计划在CS50沙箱中的工作位置,并且能够根据卡的长度和Luhn的算法确定卡是万事达卡,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的所有数字均无效。

2 个答案:

答案 0 :(得分:0)

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

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

  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,万事达卡和Discover)的卡上都有16位数字的序列。

答案 1 :(得分:0)

我发现问题是我声明了变量sum1和sum2,但是没有将它们初始化为任何值,因此将它们分配给内存中的任何值。当我将这些值初始化为0时,程序正常运行。