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

int main(void)
{
    long num = get_long("What's your card number: " );
    long countNum = num;
    int count = 0;
    while (countNum != 0)
    {
        countNum /= 10;
        count++;
    }
    printf("%i", count);
    int sum = 0;
    long tempNum = num;
    if (count == 13)
    {
        for (int i = 0; i < 7; i ++)
        {
            int n = i;
            while (n != 0)
            {
                tempNum /= 100;
                n--;
            }

            if (2 * (tempNum % 10) > 10) //should not matter if correct or incorrect in this case
            {
                sum = sum + ((2 * (tempNum % 10)) / 10) + ((2 * (tempNum % 10)) % 10);
            }
            else
            {
                sum += 2 * (tempNum % 10);
            }
            tempNum = num;
        }

        printf("%i", sum);
    }
}

I am just making this part of the algorithm for 13 digit numbers and when i test: 4222222222222 (which supposedly should work) I get a value back of 1332. Can anyone tell me where I am going wrong in my code? - I suspect something is probably wrong in the loop at the bottom.

1

There are 1 best solutions below

0
On

Seeing as this issue is still open, I thought I would go ahead and highlight the main issue with the code in that it is not including all of the digits in the hash total check. With that following is a refactored version of your program that includes the addition of the other digits to the hash total.

#include <stdio.h>

int main(void)
{
    /*  long num = get_long("What's your card number: " ); Do not have CS50 installed - using conventional input method */
    long num;
    printf("What's your card number: ");
    scanf("%ld", &num);

    long countNum = num;
    int count = 0;
    while (countNum != 0)
    {
        countNum /= 10;
        count++;
    }
    printf("%i\n", count);
    int sum = 0;
    long tempNum = num;
    if (count == 13)
    {
        for (int i = 0; i < 13; i++)    /* Evaluate every digit of the card number  */
        {
            tempNum = num % 10;
            printf("Digit is: %ld", tempNum);
            if (i % 2 != 0)             /* Parity checking - every other digit gets doubled and checked if over "9" */
            {
                tempNum *= 2;
                if (tempNum > 9)
                    tempNum -= 9;
            }
            sum += tempNum;
            printf("  Value after parity check: %ld  Running hash total: %d\n", tempNum, sum);
            num /= 10;
        }

        printf("%i ", sum);

        if ((sum % 10) == 0)
            printf("Hash total is divisible by \"10\" and therefore is valid\n");
        else
            printf("Hash total is not divisible by \"10\" so is invalid\n");
    }
}

The key bits to note are as follows:

  • All digits are being evaluated and added to the "sum" hash total variable.
  • Using a parity check (even/odd digit check), either the digit value is being added or the digit value is doubled, checked to see if the value is greater than "9" (and if so, being subtracted by "9") and then added to the "sum" hash total.

Additional print statements were added just for debugging and illustration purposes. With that following is a test of the refactored code.

craig@Vera:~/C_Programs/Console/CCLuhn/bin/Release$ ./CCLuhn 
What's your card number: 4222222222222
13
Digit is: 2  Value after parity check: 2  Running hash total: 2
Digit is: 2  Value after parity check: 4  Running hash total: 6
Digit is: 2  Value after parity check: 2  Running hash total: 8
Digit is: 2  Value after parity check: 4  Running hash total: 12
Digit is: 2  Value after parity check: 2  Running hash total: 14
Digit is: 2  Value after parity check: 4  Running hash total: 18
Digit is: 2  Value after parity check: 2  Running hash total: 20
Digit is: 2  Value after parity check: 4  Running hash total: 24
Digit is: 2  Value after parity check: 2  Running hash total: 26
Digit is: 2  Value after parity check: 4  Running hash total: 30
Digit is: 2  Value after parity check: 2  Running hash total: 32
Digit is: 2  Value after parity check: 4  Running hash total: 36
Digit is: 4  Value after parity check: 4  Running hash total: 40
40 Hash total is divisible by "10" and therefore is valid

As an additional bit of information, you might want to refer to the following Wikipedia link about the Luhn algorithm:

"https://en.wikipedia.org/wiki/Luhn_algorithm"

That might be helpful in making the card testing more generic as credit card numbers can be lengths other than thirteen digits.