-2

Why is my code wrong?? I don't know why... This problem is to get a card number from the user and tell whether it is a valid card number or an invalid card number. It could either be an American Express card, MasterCard, or a Visa. American Express card has 15 digits and must either start with 34 or 36, while MasterCard has 16 digits and can start with 51, 52, 53, 54, 55. The Visa card must either have 13 or 16 digits, and must start with a 4. This problem also uses the Luhn's algorithm wherein to check if a card number is valid every other number starting from the tens place multiplied by two, then if added the digits no their product but their digits, so if you multiply 8 by 2 its 16 so you must add 1 + 6 and the other numbers. Then once you got the sum you must add them to the ones you didn't multiply by 2, then lastly if their sum is divisible by 10 then it is valid. I really don't know where I went wrong I've been looking at my code for almost 3 hours. Also noob programmer here..

#include<stdio.h>

int main(void)
{
    //declare and initialize card number
    long long number = 0;

    //ask user for their credit card number
    do
    {
        printf("Number: ");
        scanf("%lli", &number);
    }
    while (number < 0);

    //declare and initialize a counter for the number of the digits
    int counter = 0;
    long long temp = number;

    //loop to count the number of digits
    while (temp > 0)
    {
        temp /= 10;
        counter++;
    }

    //statement for invalid digits
    if (counter != 13 && counter != 15 && counter != 16)
    {
        printf("Invalid number of digits\n");
    }

    //array to store the digits individually
    int digits[counter];

    // loop to store the digits in the array
    for (int i = 0; i < counter; i++)
    {
        digits[i] = number % 10;
        number /= 10;
    }

    //loop to multiply every other digit by 2
    for (int j = 1; j < counter; j += 2)
    {
        digits[j] *= 2;
    }

    // loop to separate then add digits that are greater than 10
    for (int x = 1; x < counter; x += 2)
    {
        if (digits[x] > 10)
        {
            int s = digits[x] % 10;
            digits[x] /= 10;
            digits[x] = (digits[x] % 10) + s;
        }
    }

    int sum = 0;

    //loop to get the sum of all numbers 
    for (int y = 0; y < counter; y++)
    {
        sum += digits[y];
    }

    sum %= 10;

    switch (sum)
    {
        case '0':
            if (counter == 15 && (digits[14] == 3 && (digits[13] == 4 || digits[13] == 7)))
            {
                printf("American Express\n");
            }
            else if (counter == 16 && digits[15] == 5)
            {
                printf("Master Card\n");
            }
            else if (counter == 13 && digits [12] == 4)
            {
                printf("Visa\n");
            }
            else if (counter == 16 && digits[15] == 4)
            {
                printf("Visa\n");
            }
            break;
        default: 
            printf("Invalid\n");
            break;
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ojou Nii
  • 244
  • 4
  • 11
  • One idea is that when you want to deal with a number as a sequence of digits, a C string (i.e. a sequence of digit characters) is more closely matching than a C integer. – unwind Mar 31 '20 at 10:02
  • can you add an example of expected output ,while your code output is wrong? – hanie Mar 31 '20 at 11:16
  • Number: 378282246310005 AMEX Number: 2221000000000009 MASTERCARD https://developer.paypal.com/docs/payflow/payflow-pro/payflow-pro-testing/#credit-card-numbers-for-testing I use that link for test numbers – Ojou Nii Mar 31 '20 at 12:26

1 Answers1

0

There are three errors, and I'm ashamed that it took myself so long to spot especially the second one.

  • if (digits[x] > 10) is a kind of off-by-one error. Rather than greater than 10, the Description of the Luhn algorithm says: If the result of this doubling operation is greater than 9 …, so this has to be if (digits[x] > 9).
  • case '0': must rather be case 0:, since sum is an integer, not a character representation.
  • if (counter == 15 && (digits[14] == 3 && (digits[13] == 4 || digits[13] == 7))) fails because the digits have been modified by the algorithm in-place, so the 7 has become a 5. We could write if (counter == 15 && (digits[14] == 3 && (digits[13] == 4 || digits[13] == 7*2-9))) instead; same for else if (counter == 16 && digits[15] == 5).
Community
  • 1
  • 1
Armali
  • 18,255
  • 14
  • 57
  • 171
  • 1
    Omg im such an idiot such careless mistakes thank you so much but I still don't quite get what you mean on your 3rd bullet... – Ojou Nii Mar 31 '20 at 12:24
  • 1
    Oh ok nvm I got what you were saying its because of the algorithm where it is multiplied by 2 then separated then added together thank you so much – Ojou Nii Mar 31 '20 at 12:45