В коде есть несколько проблем:
тип для number
должен быть unsigned long long
, чтобы он был достаточно большим для обработки 16 цифр. unsigned long
может быть достаточно большим на некоторых платформах, таких как 64-разрядная linux и OS / X, но не на других, таких как все версии Windows.
вычисления длительны и громоздки, было бы гораздо удобнее использовать массив значений di git.
неясно, вычисляете ли вы count
цифр один или несколько раз раз. L oop изменяет number
и не инициализирует count
явно (а переменная i
бесполезна). Если запустить несколько раз, это сработает случайно, поскольку number
уже будет 0
с первого запуска. Вы должны использовать временную переменную правильного типа и вычислить count
только один раз.
тесты для разных длин номеров карт могут давать ложные срабатывания: например, если m % 10 == 0
и номер карты не состоит из 13 цифр, вы напечатаете INVALID
неправильно. Тест должен быть сначала на количестве цифр, а затем на контрольной сумме.
очень запутанно называть начальные цифры как последние цифры .
Вот более простая версия с использованием массива:
#include <stdio.h>
#include <stdlib.h>
// emulate cs50 get_long_long()
static long long get_long_long(const char *prompt) {
for (;;) {
long long n;
int c;
printf("%s", prompt);
if (scanf("%llu", &n) == 1)
return n;
printf("Invalid input, try again\n");
// flush the rest of the input line
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
exit(1);
}
}
int main(void) {
long long int number, num;
int digit[16] = { 0 };
int count;
for (;;) { //getting input from the user
number = get_long_long("Please enter your 13-16 digit credit card number: \n");
if (number > 0)
break;
}
// only accept numbers with 13 to 16 digits
if (number < 1000000000000 || number > 9999999999999999) {
printf("INVALID\n");
return 1;
}
for (count = 0, num = number; num != 0; count++) {
digit[count] = num % 10;
num = num / 10;
}
// compute checksum
int checksum = 0;
for (int i = 0; i < 16; i += 2) {
int a1 = digit[i];
int a2 = digit[i + 1] * 2;
if (a2 >= 10)
a2 -= 9;
checksum += a1 + a2;
}
//printf("checksum: %d, ", checksum);
int first = digit[count - 1];
int first2 = 10 * digit[count - 1] + digit[count - 2];
if (checksum % 10 == 0) {
if (count == 16) {
if (first2 >= 51 && first2 <= 55) {
printf("MASTERCARD\n");
return 0;
} else
if (first == 4) {
printf("VISA\n");
return 0;
}
} else
if (count == 13) {
if (first == 4) {
printf("VISA\n");
return 0;
}
} else
if (count == 15) {
if (first2 == 34 || first2 == 37) {
printf("AMEX\n");
return 0;
}
}
}
printf("INVALID\n");
return 1;
}