1

I have basically no coding experience and am enrolled in CS50x on edX. I am currently working on Problem Set 1's Credit problem (in the C language). My program uses Luhn's Algorithm to determine whether a credit card number belongs to American Express, MasterCard, or Visa. When I test the program, inputing test credit card numbers gives me responses I don't want; every valid (test) credit card number I input gives no output.

I've been fighting with this for a few days. There was a point where my program recognized all 3 credit card company numbers, but allowed any random number to be inputted, while I wanted the program to print "INVALID" if that was the case.

Another problem I've had is getting an error for my integer variable, digitcount, (see code below) not being declared as a variable in one line of code (even though there are a few lines of code where digitcount is recognized just fine?)

I had fixed some of these bugs by reading into the error messages I got, but sometimes I can't understand them and just messing around ends up fixing them. It makes no sense to me. (Such as deleting or moving parenthesis and interchanging == with =.)

I have also tried looking at other peoples' codes, but when I try to use similar concepts to what I see, my program doesn't work.

Sorry if any of this is messy or hard to read! Even though I've been trying to teach myself what I need to know to make this work, I often get confused when using variable names like "n" and need some separation between certain parts of the code so I don't feel unorganized.

I could just skip Credit since I've done all the other problems in Problem Set 1, but I really want to learn and use any knowledge I come across to complete and understand as much as I can.

Here's my code! Many thanks to anyone who decides to take a look and help me understand where I'm wrong!

#include <cs50.h>
#include <math.h>

int main(void)
{
    long long CCnumber;
    
    //prompts the user for a credit card number
    do
    {
        CCnumber = get_long_long("Enter your Credit Card Number: ");
    }
    while (CCnumber < 0);
    
    
    //--------------------
    
    
    //defines counter as a long type variable and digitcount as an integer type variable
    int counter = 0;
    int digitcount = 0;
    
    //loop the counts the digit-length of the credit card number
    while (counter > 0)
    {
        counter = CCnumber / 10;
        digitcount++;
    }
    
    
    //--------------------
    
    
    //grabs every other digit in the credit card number, starting from the second to last digit
    //% grabs the remainder of a number divided, while / grabs the quotient of the number divided
    int digit1 = (((CCnumber % 100) / 10) * 2);
        int digit1a = (digit1 / 10);
        int digit1b = (digit1 % 10);
    int digit2 = (((CCnumber % 10000) / 1000) * 2);
        int digit2a = (digit1 / 10);
        int digit2b = (digit1 % 10);
    int digit3 = (((CCnumber % 1000000) / 100000) * 2);
        int digit3a = (digit1 / 10);
        int digit3b = (digit1 % 10);
    int digit4 = (((CCnumber % 100000000) / 10000000) * 2);
        int digit4a = (digit1 / 10);
        int digit4b = (digit1 % 10);
    int digit5 = (((CCnumber % 10000000000) / 1000000000) * 2);
        int digit5a = (digit1 / 10);
        int digit5b = (digit1 % 10);
    int digit6 = (((CCnumber % 1000000000000) / 100000000000) * 2);
        int digit6a = (digit1 / 10);
        int digit6b = (digit1 % 10);
    int digit7 = (((CCnumber % 100000000000000) / 10000000000000) * 2);
        int digit7a = (digit1 / 10);
        int digit7b = (digit1 % 10);
    int digit8 = (((CCnumber % 10000000000000000) / 1000000000000000) * 2);
        int digit8a = (digit1 / 10);
        int digit8b = (digit1 % 10);
        
    //adds all the digits together
    int checksum1 = (digit1a + digit1b + digit2a + digit2b + digit3a + digit3b + digit4a + digit4b + digit5a + digit5b + digit6a + digit6b +digit7a +digit7b + digit8a +digit8b);
    
    //grabs all the other digits from the credit card number
    int otherdigit1 = ((CCnumber % 10) / 1);
    int otherdigit2 = ((CCnumber % 1000) / 100);
    int otherdigit3 = ((CCnumber % 100000) / 10000);
    int otherdigit4 = ((CCnumber % 10000000) / 1000000);
    int otherdigit5 = ((CCnumber % 1000000000) / 100000000);
    int otherdigit6 = ((CCnumber % 100000000000) / 10000000000);
    int otherdigit7 = ((CCnumber % 10000000000000) / 1000000000000);
    int otherdigit8 = ((CCnumber % 1000000000000000) / 100000000000000);
    
    //adds all the other digits together
    int checksum2 = (otherdigit1 + otherdigit2 + otherdigit3 + otherdigit4 + otherdigit5 + otherdigit6 + otherdigit7 + otherdigit8);
    
    //adds the checksum halfs together
    int TOTALchecksum = (checksum1 + checksum2);
    
    //checks the last digit of the total checksum
    int lastdigit =  (TOTALchecksum / 1);
    
    
    //--------------------
    
    
    //determines what the credit card number's first and second digits are (15-digit count)
    int startingdigit115 = (CCnumber / 100000000000000);
    int startingdigit215 = ((CCnumber / 10000000000000) % 10);
    
    int startingdigitsum15 = (startingdigit115 + startingdigit215);
    
    //determines what the credit card number's first and second digits are (16-digit count)
    int startingdigit116 = (CCnumber / 1000000000000000);
    int startingdigit216 = ((CCnumber / 100000000000000) % 10);
    
    int startingdigitsum16 = (startingdigit116 + startingdigit216);
    
    //determines what the cred card number's first and second digits are (13-digit count)
    int startingdigit113 = (CCnumber / 1000000000000);
    int startingdigit213 = ((CCnumber / 100000000000) % 10);
    
    int startingdigitsum13 = (startingdigit113 + startingdigit213);
    
    
    //--------------------

    if ((lastdigit == 0) && (digitcount == 15))
    {
        //determines if credit card number belongs to American Express
        if (startingdigitsum15 == 7 || startingdigitsum15 == 10)
        {
            printf("AMEX\n");
        }
    }
    
    else if ((lastdigit == 0) && (digitcount == 16))
    {
        //determines if credit card number belongs to MasterCard
        if (startingdigitsum16 == 6 || startingdigitsum16 == 7 || startingdigitsum16 == 8 || startingdigitsum16 == 9 || startingdigitsum16 == 10)
        {
            printf("MASTERCARD\n");
        }
    }
    
    else if ((lastdigit == 0 && digitcount == 13) || (lastdigit == 0 && digitcount == 16))
    {
        //determines if credit card number belongs to Visa
        if ((startingdigit113 == 4 || startingdigit116 == 4))
        {
            printf("VISA\n");
        }
    }
    
    else if ((lastdigit == 0 && digitcount != 13) || (lastdigit == 0 && digitcount != 15) || (lastdigit == 0 && digitcount != 16))
    {
        printf("INVALID\n");
    }
    
}```
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
RomVHS
  • 11
  • 3
  • Be careful in your digit counting `while` loop. If the value of `CCnumber` is greater than or equal to `10`, that loop becomes infinite. Try creating another variable before entering the loop and assign its value to `CCnumber`; then, decrement it in the loop dividing by 10. **BTW**, assigning `counter` to 0 and testing for `while (counter > 0)` is wrong as well. It never enters into the loop this way (and will never exit once inside). – ssd Aug 05 '20 at 01:28
  • 1
    Another problem: What happens if the credit card number starts with a `0` (or a bunch of zeroes). Your algorithm will fail to count number of digits in this case as well. You'd better revise your algorithm for counting digits. – ssd Aug 05 '20 at 01:39
  • @ssd Thanks for the information on the while loop! I ended up coding this out, and it seems to work well, but I'm still trying to figure out how to count the zeros! ` int digitcount = 0; long long ccn = CCnumber; while (ccn > 0) { ccn = ccn / 10; digitcount++; }` – RomVHS Aug 05 '20 at 03:38

1 Answers1

1

Counting leading zeroes is a little hard with numeric input. Maybe you should read the card number as string into a char * array using scanf; then, validate the CCNumber.

...
...
...
// max CCNumber char length is 16, plus 1 for string terminator '\0' = 17 chars
char CCNumber[17];
int notValidInput = 1;
int digitCount = 0;

while (notValidInput) {
    notValidInput = 0;
    scanf("%s", CCNumber);
    digitCount = 0;

    while (CCNumber[digitCount] != '\0') {
        // CCNumber character validation
        if (CCNumber[digitCount] < '0' || CCNumber[digitCount] > '9') {
            notValidInput = 1;
            printf("error: must contain numeric chars.\n");
            break;
        }
        else {
            digitCount++;
        }
    }
...
...
...
}
ssd
  • 2,340
  • 5
  • 19
  • 37