Нужна обратная связь: кредит (Pset1- CS50x) - PullRequest
0 голосов
/ 12 июля 2020
#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void) {
    long int number;
    int count = 0;  // starting the count counter
    do {
        number = get_long("Please enter your 13-16 digit credit card number: \n"); //getting input from the user
    } while (number <= 0);

    int d1 = number % 10;                                           //separating digit number 1
    int d2 = ((number % 100) / 10);                                 //separating digit number 2
    int d3 = ((number % 1000) / 100);                               //separating digit number 3
    int d4 = ((number % 10000) / 1000);                             //separating digit number 4
    int d5 = ((number % 100000) / 10000);                           //separating digit number 5
    int d6 = ((number % 1000000) / 100000);                         //separating digit number 6
    int d7 = ((number % 10000000) / 1000000);                       //separating digit number 7
    int d8 = ((number % 100000000) / 10000000);                     //separating digit number 8
    int d9 = ((number % 1000000000) / 100000000);                   //separating digit number 9
    int d10 = ((number % 10000000000) / 1000000000);                //separating digit number 10
    int d11 = ((number % 100000000000) / 10000000000);              //separating digit number 11
    int d12 = ((number % 1000000000000) / 100000000000);            //separating digit number 12
    int d13 = ((number % 10000000000000) / 1000000000000);          //separating digit number 13
    int d14 = ((number % 100000000000000) / 10000000000000);        //separating digit number 14
    int d15 = ((number % 1000000000000000) / 100000000000000);      //separating digit number 15
    int d16 = ((number % 10000000000000000) / 1000000000000000);    //separating digit number 16
    int last13 = number / 1000000000000;        //finding the last one digit of 13 digit VISA
    int last15 = number / 10000000000000;       //finding the last two digit of 15 digit AMEX
    int last16v = number / 1000000000000000;    //finding the last one digit of 16 digit VISA
    int last16m = number / 100000000000000;     //finding the last two digit of 16 digit MASTERCARD
    int a2 = (d2 * 2);
    int a4 = (d4 * 2);
    int a6 = (d6 * 2);
    int a8 = (d8 * 2);
    int a10 = (d10 * 2);
    int a12 = (d12 * 2);
    int a14 = (d14 * 2);
    int a16 = (d16 * 2);
    if (a2 >= 10) {             // separating the digits of the multiple
        int a11a = (a2 % 100) / 10;
        int a12a = (a2 % 10);
        a2 = a11a + a12a;
    }
    if (a4 >= 10) {           // separating the digits of the multiple
        int a31 = (a4 % 100)  / 10;
        int a32 = (a4 % 10);
        a4 = a31 + a32;
    }
    if (a6 >= 10) {             // separating the digits of the multiple
        int a51 = (a6 % 100) / 10;
        int a52 = (a6 % 10);
        a6 = a51 + a52;
    }
    if (a8 >= 10) {              // separating the digits of the multiple
        int a71 = (a8 % 100) / 10;
        int a72 = (a8 % 10);
        a8 = a71 + a72;
    }
    if (a10 >= 10) {        // separating the digits of the multiple
        int a91 = (a10 % 100) / 10;
        int a92 = (a10 % 10);
        a10 = a91 + a92;
    }
    if (a12 >= 10) {              // separating the digits of the multiple
        int a111 = (a12 % 100) / 10;
        int a112 = (a12 % 10);
        a12 = a111 + a112;
    }
    if (a14 >= 10) {               // separating the digits of the multiple
        int a131 = (a14 % 100) / 10;
        int a132 = (a14 % 10);
        a14 = a131 + a132;
    }
    if (a16 >= 10) {              // separating the digits of the multiple
        int a151 = (a16 % 100) / 10;
        int a152 = (a16 % 10);
        a16 = a151 + a152;
    }
    int b = d1 + d3 + d5 + d7 + d9 + d11 + d13 + d15;
    int c = a2 + a4 + a6 + a8 + a10 + a12 + a14 + a16;
    int l = b + c;
    int j = a2 + a4 + a6 + a8 + a10 + a12;
    int k =  d1 + d3 + d5 + d7 + d9 + d11 + d13;
    int m = j + k;
    int e = d1 + d3 + d5 + d7 + d9 + d11 + d13 + d15;
    int x = a2 + a4 + a6 + a8 + a10 + a12 + a14;
    int n = x + e;
    printf("%i", n);
    if (l % 10 == 0) {                     //checking if the checksum is valid
        for (int i = number; number != 0; i++) {   // counting the credit card number
            number /= 10;
            count++;
        }
        if (count == 16) {
            if (last16m == 51) {             // checking the last two digit of credit card
                printf("MASTERCARD\n");   // printing the result based on last two digits
            } else
            if (last16m == 52) {       // checking the last two digit of credit card
                printf("MASTERCARD\n");   // printing the result based on last two digits
            } else
            if (last16m == 53) {        // checking the last two digit of credit card
                printf("MASTERCARD\n");     // printing the result based on last two digits
            } else
            if (last16m == 54) {            // checking the last two digit of credit card
                printf("MASTERCARD\n");          //// printing the result based on last two digits
            } else
            if (last16m == 55) {               // checking the last two digit of credit card
                printf("MASTERCARD\n");         // printing the result based on last two digits
            } else
            if (last16v == 4) {                // checking the last two digit of credit card
                printf("VISA\n");              // printing the result based on last two digits
            } else {
                printf("INVALID\n");
            }
            if (count != 16) {
                printf("INVALID\n");
            }
        } else {
            printf("INVALID\n");
        }
    }

    if (m % 10 == 0) {                    //checking if the checksum is valid
        for (int i = number; number != 0; i++) {       // counting the credit card number
            number /= 10;
            count++;
        }
        if (count == 13) {
            if (last13 == 4) {   // checking the last one digit of credit card
                printf("VISA\n");       // printing the result based on last one digit
            } else {
                printf("INVALID\n");
            }
        } else {
            printf("INVALID\n");
        }
    }
    if (n % 10 == 0) {                  //checking if the checksum is valid
        for (int i = number; number != 0; i++) {        // counting the credit card number
            number /= 10;
            count++;
        }

        if (count == 15) {
            if (last15 == 34) {     // checking the last two digit of credit card
                printf("AMEX\n");         // printing the result based on last two digits
            } else
            if (last15 == 37) {      // checking the last two digit of credit card
                printf("AMEX\n");        // printing the result based on last two digits
            } else {
                printf("INVALID\n");
            }

            if (count != 15) {
                printf("INVALID\n");
            }
        } else {
            printf("INVALID\n");
        }
    }
}

Я пробовал использовать 4003600000000014, и он дает правильный результат. Принимая 4222222222222, возвращает INVALID. Это также не работает для номеров AMEX (15 цифр). Он не отвечает на ввод 4111111111111113 (должен возвращать 0). Подскажите пожалуйста, что не так, я новичок ie в программировании. Это результат, который он дает при проверке с помощью check50 https://submit.cs50.io/check50/44370b403c33f9b47d462e3278458901599d16e1.

1 Ответ

0 голосов
/ 13 июля 2020

В коде есть несколько проблем:

  • тип для 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;
}
...