谁能帮我检查一下我的Luhns算法代码的错误吗?

问题描述 投票:0回答:1

我是 c 语言新手,正在学习 cs50 课程第一周。
似乎无法处理检查 cs50 指示的 2 个错误。

我写了这个版本的信用卡号检查代码,但当我检查时它仍然给我一个错误。
显然,它会将 4111111111111113 和 4222222222223 验证为签证号码,而实际上它们不是。 (显示无效校验和)

这是我的代码:

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

int main(void)
{
    long long card_num = 0LL;
    do 
    {
        card_num = get_long_long("Number: ");
    }
    while (card_num < 1LL || card_num > 9999999999999999LL);

    int sum = 0;
    long long temp_num = card_num;
    int count = 0;

    for (int i = 1; i <= count; i++)
    {
        int digit = temp_num % 10LL;
        if (i % 2 == 0) 
        {
            digit *= 2;

            if (digit > 9)
            {
                digit -= 9;
            }
        }
        sum += digit;  

        temp_num /= 10LL;
        count++; 
    }

    if (sum % 10 != 0)     
    {
        printf("INVALID\n");
        return 0;
    }
    else
    {
        long long temp_num = card_num;

        int count = 0;

        while (temp_num > 0LL)
        {
            temp_num = temp_num / 10LL;
            count++;
        }

        if (count != 13 && count != 15 && count != 16)
        {
            printf("INVALID\n");
            return 0;
        }

        temp_num = card_num;                                                                
        while (temp_num > 100LL)
        {
            temp_num = temp_num / 10LL;
        }

        int company_id = temp_num;
        if (company_id > 50 && company_id < 56 && count == 16)
        {
            printf("MASTERCARD\n") ;
        }
        else if ((company_id == 34 || company_id == 37) && (count == 15))
        {
            printf("AMEX\n") ;
        }
        else if ((company_id / 10 == 4) && (count == 13 || count == 16 || count == 19)) 
        {
            printf("VISA\n") ;
        }
        else
        {
            printf("INVALID\n");
        }

    }
}
c cs50 luhn
1个回答
0
投票

在测试代码并添加一些临时 printf 语句时,很快就发现问题是 Luhn 检查值“for”循环未执行,因为变量“count”已定义并初始化为零值。

    int sum = 0;
    long long temp_num = card_num;
    int count = 0;                      /* Problem variable - set to zero */

    for (int i = 1; i <= count; i++)    /* Since count is zero, the for loop never executes */
    {
        int digit = temp_num % 10LL;
        if (i % 2 == 0) 
        {
            digit *= 2;

            if (digit > 9)
            {
                digit -= 9;
            }
        }
        sum += digit;  

        temp_num /= 10LL;
        count++; 
    }

这样,变量“sum”将包含零值,并且“if (sum % 10 != 0)”测试将为假,这会导致程序继续运行并错误地将输入的测试编号识别为有效“VISA”号码。

接下来是该代码块的重构版本,利用字符串功能。

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

int main(void)
{
    long long card_num = 0LL;
    char text[20];
    do
    {
        //card_num = get_long_long("Number: ");
        printf("Number: ");
        scanf("%lld", &card_num);
    }
    while (card_num < 1LL || card_num > 9999999999999999LL);

    int sum = 0;
    long long temp_num = card_num;
    sprintf(text, "%lld", card_num);

    for (int i = 1; i <= strlen(text); i++)
    {
        int digit = temp_num % 10LL;
        if (i % 2 == 0)
        {
            digit *= 2;

            if (digit > 9)
            {
                digit -= 9;
            }
        }

        printf("Digit: %d\n", digit);   /* Low tech debug method to monitor Luhn calculation    */
        sum += digit;
        temp_num /= 10LL;
    }

    printf("Sum: %d\n", sum);           /* Low tech debug method to monitor Luhn calculation    */

仅供参考,如上所述,由于我的系统上没有 CS50 库和功能,我用“printf”提示语句和“scanf”语句替换了输入信用卡号;但是,它实际上正在获取信用卡号。通过重构的程序,以下是利用您的信用卡示例之一进行的测试。

craig@Vera:~/C_Programs/Console/CreditLuhn/bin/Release$ ./CreditLuhn
Number: 4111111111111113
Digit: 3
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 8
Sum: 32
INVALID

如上所述,最终总和不能被“10”整除,因此请注意输入的数字无效。

可能需要对代码进行额外的润色,但最重要的是熟悉调试,即使它就像临时插入“printf”语句一样简单。

© www.soinside.com 2019 - 2024. All rights reserved.