I attempted Problem Set 1's 'More Comfortable' Credit assignment today, which is essentially to implement Luhn's mod 10
algorithm for checking that a given debit/credit card number is valid. I've managed to implement this section fairly easily. The final part of the assignment is to determine which vendor the card was issued by (American Express, Visa, or MasterCard).
I tested my original program with several inputs, both valid, incorrect, with strings and characters etc. to check that it would accept correct numbers and reject junk input. When I tried to submit this to CS50's automated system, I got a few failed tests:
:( identifies 369421438430814 as INVALID
expected "INVALID\n", not ""
:( identifies 4062901840 as INVALID
expected "INVALID\n", not ""
:( identifies 5673598276138003 as INVALID
expected "INVALID\n", not ""
You can see that my program just returns nothing here. I littered my code with printf()
statements to check that everything up to that point was working correctly. I strongly suspect that these numbers are technically correct as per the algorithm but don't belong to any vendor. I added an else block to the end of my card testing function, but it never runs. I know that there can be no other statements between an if
and the following else
. The code looks like this:
void returnCardType(int *digitArr, int numberDigits)
{
// Get the first couple of digits to check the card type against
int firstDig = digitArr[numberDigits - 1]; // Don't forget we filled the
int secondDig = digitArr[numberDigits - 2]; // array in reverse order
bool unspecifiedVendor = true;
printf("\nFirst digit: %d\nSecond digit: %d\n", firstDig, secondDig);
// Is it American Express?
if (numberDigits == 15 && firstDig == 3)
{
if (secondDig == 4 || secondDig == 7)
{
printf("AMEX\n");
unspecifiedVendor = false;
}
}
//printf("AMEX passed over.\n");
// Is it MasterCard?
if (numberDigits == 16 && firstDig == 5)
{
if (secondDig == 1 || secondDig == 2 || secondDig == 3 || secondDig == 4 || secondDig == 5)
{
printf("MASTERCARD\n");
unspecifiedVendor = false;
}
}
//printf("MasterCard passed over. \n");
// Is it Visa?
if (numberDigits == 13 || numberDigits == 16)
{
if (firstDig == 4)
{
printf("VISA\n");
unspecifiedVendor = false;
}
}
else //(unspecifiedVendor == true)
{
printf("INVALID\n");
}
//printf("Final 'else' statement passed over.\n");
//printf("\nCard does not belong to any of the above vendors.\n");
}
Unless I'm just completely brain-farting on this, my logic here is that the else
block will run for any card number that isn't a Visa, AMEX, or MasterCard. My first instinct is to add some return
statements to the if
statements here so that the function terminates, but this isn't in the spec and would cause my output to differ from the staff implementation's output.
You can see my solution (commented out) was to use a bool flag unspecifiedVendor
and then to run the final if
block should none of the others run and toggle it off. This seems to be a functioning work-around, but I'm still confused as to why the original else
block didn't work. I think I'm being really stupid.
I also tried changing the second and third if
's to else if
's, to no effect. Thanks in advance for the information!