Напишите программу на 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");
}