【问题标题】:CS50 pset1 Credit error in checksum calculationCS50 pset1 校验和计算中的信用错误
【发布时间】:2021-06-26 20:38:53
【问题描述】:

这是我在这里的第一篇文章,如果我犯了任何错误,请告诉我。我试图在这里找到我的问题的答案,但我找不到任何合适的东西。

所以我在 CS50x 第 1 周的“信用”问题集的代码中存在问题。 在问题集中,用户必须输入一个信用卡号,我们必须将其验证为 VISA、MASTERCARD 或 AMEX。否则输出应该是无效的。

验证应该是这样的:

4 0 0 3 6 0 0 0 0 0 >0 0 0 0 1 4

从第二个到最后一个数字(粗体)开始的每个第二个数字乘以 2 并相加。 但是,如果相乘的数字有 2 位,则这两个数字将单独相加,例如:

2 * 6 = 12 所以十二点就是 1 + 2

然后你取另一半数字(不相乘)并将它们加在一起,所以最后你有类似的东西

8 + 0 + 1 + 2 + 0 + 0 + 0 + 0 + 2 = 13(以粗体显示的数字)

0 + 3 + 0 + 0 + 0 + 0 + 0 + 4 = 7(对于另一半数字)

将两者相加得到 20(在问题集中称为 校验和。如果计算出的数字的最后一位是 0 该卡是有效的,之后您只需检查一些条件即可判断它是 AMEX、VISA 还是 MASTERCARD。

不同信用卡的条件:

美国运通 = 15 位,以 34 或 37 开头

VISA = 13 或 16 位,从 4 开始

万事达卡 = 16 位,以 51、52、53、54 或 55 开头

(抱歉介绍太长了)

我试图为这个计算制定一个公式,但由于某种原因,它不适用于我们测试它的所有数字。我尝试了很多方法来更改代码末尾的计算和条件,但是每次我解决一个问题时,都会出现另一个问题,现在感觉就像我以为自己陷入了兔子洞,所以也许我太盲目了看到明显的。

到目前为止,我们只使用库 - -

    long checkcredit = store;
    int sum1 = 0;
    int sum2;
    for (int duo = 0; checkcredit > 0; duo++, checkcredit /= 10)
    {
        if (duo % 2 == 0)
        {
            sum1 += (checkcredit % 10);
        }
        else
        {
            sum2 = (checkcredit % 10) * 2;
            if (sum2 >10)
            {
                sum2 = (checkcredit % 10) + 1;
            }
        }
    }
    sum1 +=sum2;
    sum1 = sum1 % 10;

这是我认为问题所在的部分,因为我打印了 sum1(计算出的长数字的验证号),并且有时输出错误。

store 是信用卡号的原始值(例如 4003600000000014)

checkcredit 只是 store 的复制品,可以在不更改原始 store 价值的情况下使用

sum1 用于数字以粗体显示(在添加前乘以 2 的一次)

sum2 是数字的另一半

duo 是一个数字计数器,用于计算当前数字是否相乘 (感谢我的一位同事暗示我可以尝试这种方式,我的旧版本长了 4 倍

最后我只是将 sum1sum2 加在一起得到 "Checksum"

没有任何编译器错误,只是 Check50 输出

check50 v3.2.2 生成的 cs50/problems/2021/x/credit 的结果

:) credit.c 存在

:) credit.c 编译

:(将378282246310005识别为AMEX 应为“AMEX\n”,而不是“INVALID\n”

:( 将 371449635398431 识别为 AMEX 应为“AMEX\n”,而不是“INVALID\n”

:( 将 5555555555554444 识别为 MASTERCARD 应为“MASTERCARD\n”,而不是“INVALID\n”

:( 将 5105105105105100 识别为 MASTERCARD 应为“MASTERCARD\n”,而不是“INVALID\n”

:( 将 4111111111111111 识别为 VISA 应为“VISA\n”,而不是“INVALID\n”

:(将4012888888881881识别为VISA 应为“VISA\n”,而不是“INVALID\n”

:) 将 4222222222222 识别为 VISA

:) 将 1234567890 标识为无效

:) 将 369421438430814 标识为无效

:) 将 4062901840 标识为无效

:) 将 5673598276138003 标识为无效

:) 将 4111111111111113 标识为无效

:) 将 4222222222223 标识为无效

就像我说的,我认为我犯的错误出在这部分代码中(我什至认为它与 for 循环中的条件有关)但我想不通找出那里出了什么问题。

以防万一整个代码都在这里:

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

int main(void)
{
    //Ask user for credit card number
    long store;
    do
    {
        store = get_long("Number: ");
    }
    while (store < 0);

    //calculating the amount of digits 
    long cnumber = store;
    int digits;

    for (digits = 0 ; cnumber > 0 ; digits++)
    {
        cnumber/=10;
    }

    //calculating the checksum
    long checkcredit = store;
    int sum1 = 0;
    int sum2;
    for (int duo = 0; checkcredit > 0; duo++, checkcredit /= 10)
    {
        if (duo % 2 == 0)
        {
            sum1 += (checkcredit % 10);
        }
        else
        {
            sum2 = (checkcredit % 10) * 2;
            if (sum2 >10)
            {
                sum2 = (checkcredit % 10) + 1;
            }
            //sum1 += sum2;
        }
    }
    sum1 +=sum2;
    //printf("%i ", sum1);
    sum1 = sum1 % 10;

    //conditions for varification of the card
    if (sum1 == 0)
    {
        if (digits != 13 && digits != 15 && digits != 16)
        {
            printf("INVALID\n");
        }
        else if (digits == 16 || digits == 13)
        {
            if (digits == 16 && (store >= 51e14 && store <56e14))
            {
                printf("MASTERCARD\n");
            }
            else if ((digits == 13 || digits == 16) && ((store <= 4e13 && store < 5e13)||(store >= 4e15 && store < 5e15)))
            {
                printf("VISA\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }    
        else if (digits == 15)
        {
            if((store >= 34e13 && store < 35e13)||(store >= 37e13 && store < 38e13))
            {
                printf("AMEX\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
    }
    else
    {
        printf("INVALID\n");
    }
}

请忽略最后的条件部分,我只是将它一起原型化以检查它是否有效(如果我忽略校验和条件,它会这样做)

对于这篇长篇文章我深表歉意,我真的很感谢所有花时间研究这个并帮助初学者从错误中吸取教训的人。

-Wannabree

【问题讨论】:

  • 为了使 sum2 成为 sum,您必须像对 sum1 所做的那样总结一些东西(包括初始化),而不是分别覆盖它时间。

标签: c loops for-loop formula cs50


【解决方案1】:

sum2 的处理是错误的,它没有总结一些东西,而是每次都覆盖sum2。一种可能的补救措施是初始化int sum2 = 0; 并更改

        {
            sum2 = (checkcredit % 10) * 2;
            if (sum2 >10)
            {
                sum2 = (checkcredit % 10) + 1;
            }
        }

            sum2 += "\0\2\4\6\x8\1\3\5\7\x9"[checkcredit % 10];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-30
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 2021-04-05
    • 1970-01-01
    • 2010-12-01
    相关资源
    最近更新 更多