Напишите программу на C, чтобы применить алгоритм Луна для проверки кредитных карт

Я совершенно новичок в C (и во всех формах программирования...) и после класса CS50 в этом году. Мне действительно тяжело писать простую программу, которая использует алгоритм Луна для проверки правильности номеров кредитных карт.

Мне нужна моя программа, чтобы запросить ввод данных у пользователя и повторить запрос на случай, если ввод не соответствует формату кредитной карты (например, отрицательные числа или буквы и т. Д.), А затем применить алгоритм, чтобы узнать, является ли число действительный номер кредитной карты, и если да, будь то Visa, MasterCard или AmEx.

Я знаю, что на этот вопрос ответили с помощью различных кодов на этом сайте, я клянусь, что прочитал все, что мог найти (на этом сайте и в других местах в сети), но мне очень трудно понять синтаксис C, и я хотел попытаться придумать что-то сам вместо того, чтобы копировать биты кодов, которые я не понимаю из других ответов. Если кто-то может мне помочь, посмотреть на то, что я уже сделал, и сказать, что я делаю неправильно, я был бы очень благодарен. Кроме того, любые советы, которые могли бы помочь мне лучше понять синтаксическую логику C, были бы чрезвычайно полезны, опять же, я совершенно новичок (3 недели на изучение программирования на самостоятельной основе...) .

Моя программа компилируется, но когда я запускаю ее, она ведет себя очень странным образом: когда я ввожу ввод, иногда он говорит, что он недействителен (даже если это допустимое число), а иногда он просто ничего не возвращает после нажатия введите и не прекратите работу, независимо от того, сколько раз я нажимаю клавишу возврата.

Вот мой код до сих пор:

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

int main(void)
{
    printf("Please give me your credit card number:\n") ;

    long long card_num ;

    do
    {
        card_num = GetLongLong() ;
    }
    while (card_num < 1 || card_num > 9999999999999999) ;

    // Make a copy of the card number to be used and modified throughout the process.

    long long temp_num = card_num ;
    int digit = 0 ;
    int count = 0 ;
    int sum_a = 0 ;
    int sum_b = 0 ;

    // Isolate every digit from the credit card number using a loop and the variable 'digit'.
    // Keep track of the amount and position of each digit using variable 'count'.

    while (card_num >= 0)
    {
        digit = card_num % 10 ;
        count++ ;
        temp_num = (card_num - digit) / 10 ;
        break ;


     // Apply Luhn's algorithm using two different 'for' loops depending on the position of each digit.

        for (count = 0 ; count % 2 == 0 ; count++)
        {
            sum_a = sum_a + ((card_num % 10) * 2) ;

            while ((card_num % 10) * 2 >= 10)
            {
                sum_a = (sum_a % 10) + 1 ;
            } 
        }

        for (count = 0 ; count % 2 != 0 ; count++)
        {
            sum_b = sum_b + digit ;
        }

        return sum_a ;
        return sum_b ;
        return count ;
    }

    // Checking the validity of the number according to Luhn's algorithm

    int total_sum = sum_a + sum_b ;

    if (total_sum % 10 != 0)
    {
       printf("This is an invalid number.\n") ; 
    }

// If the number entered doesn't have the right amount of digits according
// to variable 'count', declare the number as invalid.

    if (count != 13 || count != 15 || count != 16)
    {
        printf("This is an invalid number.\n") ;
    }

// Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits. 
// Store the results in a variable 'company_id'.

    temp_num = card_num ;
    int company_id ;

    while (temp_num > 100)
    {
        temp_num = card_num - (card_num % 10) ;
        company_id = temp_num / 10 ;
    }

    return company_id ;

// Print the type of credit card depending on the company ID and amount of digits.

    if (company_id > 50 && company_id < 56 && count == 16)
    {
        printf("MASTERCARD\n") ;
    }
    else if ((company_id == 4) && (count == 13 || count == 16))
    {
        printf("VISA\n") ;
    }
    else if ((company_id == 34 || company_id == 37) && (count == 15)) 
    {
        printf("AMEX\n") ;
    }
    else
    {
        printf("This is an invalid number.\n") ;
    }

    return 0 ;

}

1 ответ

Решение

Ваш ответ - неупорядоченная стилизация с разделами, которые логически не следуют из предыдущего.

Конкретные вопросы:

Это логика:

if (count != 13 || count != 15 || count != 16)

делает недействительной каждую карту, для этого должно быть или s (||), и s (&&).

Этот цикл не имеет смысла:

while (card_num >= 0)
{
    digit = card_num % 10 ;
    count++ ;
    temp_num = (card_num - digit) / 10 ;
    break ;
    ...
}

break является безусловным, поэтому он выходит из цикла и игнорирует следующие двадцать строк.

Вы, кажется, слились в подпрограммах из других мест, как вы называете return пять раз, только последний из которых действителен:

return sum_a ;
return sum_b ;
return count ;
return company_id ;
return 0 ;

В нескольких местах вы используете card_num когда вы должны использовать temp_num,

Вы не можете выйти из программы, когда узнаете, что карта недействительна - вместо этого вы просто продолжаете тестирование. Вы не можете подтвердить, когда карта действительна.

Вы подсчитываете количество цифр в номере карты, но ждете, пока не пройдете другие проверки, прежде чем проверять, был ли этот счетчик цифр действительным или нет.

Далее следует моя доработка вашего кода для решения вышеуказанных и некоторых проблем со стилем:

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

int main(void)
{
    printf("Please give me your credit card number: ") ;

    long long card_num = 0LL;

    while (card_num < 1LL || card_num > 9999999999999999LL)
    {
        card_num = GetLongLong();
    }

    // Make a copy of the card number to be used and modified throughout the process.

    long long temp_num = card_num;

    // Isolate every digit from the credit card number using a loop and the variable 'digit'.
    // Keep track of the amount and position of each digit using variable 'count'.

    int count = 0;

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

    // If the number entered doesn't have the right amount of digits according
    // to variable 'count', declare the number as invalid.

    if (count != 13 && count != 15 && count != 16)
    {
        printf("This is an invalid number (# of digits).\n");
        return 1;
    }

    // Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits. 
    // Store the results in a variable 'company_id'.

    temp_num = card_num;

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

    int company_id = temp_num;

    // Print the type of credit card depending on the company ID and amount of digits.

    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("This card was issued by an unknown company.\n");
    }

    // Apply Luhn's algorithm.

    int sum = 0;

    temp_num = card_num;

    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;
    }

    // Checking the validity of the number according to Luhn's algorithm

    if (sum % 10 != 0)
    {
        printf("This is an invalid number (Luhn's algorithm).\n");
        return 1; 
    }

    printf("This is a valid number.\n");

    return 0;
} 

Это не законченная программа - есть проверка ошибок и другие необходимые детали. Вместо суммирования цифр, когда удвоенный номер карты больше 9, я использовал более простой подход вычитания 9.

Здесь мое решение, этот метод получил длинный номер кредитной карты var, я надеюсь быть полезным.

void check_card(long n)

{
    long temp_n = n;
    int count = 2;
    while(temp_n > 100)
    {
        temp_n = temp_n / 10;
        count ++;
    }

    long temp_n2 = n;
    int sum = 0;

    for (int i = 1; i <= count; i++)
    {
        int digit = temp_n2 % 10;
        if (i%2 == 0)
        {
            if (digit * 2 > 9)
            {
                sum += (digit * 2) - 9;
            }
            else
            {
                sum += digit * 2;
            }
        }
        else
        {
             sum += digit;
        }  
        temp_n2 /= 10;
    }

    bool flag = (sum % 10 == 0) ? true : false;

    if (count == 15 && (temp_n == 34 || temp_n == 37) && flag)
    {
        printf("AMEX\n");
    }
    else if(count == 16 && (temp_n > 50 && temp_n < 56) && flag)
    {
        printf("MASTERCARD\n");
    }
    else if((count == 13 || count == 16) && (temp_n / 10 ==4) && flag)
    {
        printf("VISA\n");
    }
    else
    {
        printf("INVALID\n");
    }        
Другие вопросы по тегам