This is my first post on here so please tell me if i made any mistakes. I tried to find an answer to my question on here but i couldn't find anything fitting.
so i have a problem in my code for the 'Credit' problem set of CS50x's week 1. In the problemset the user has to enter a creditcard number that we have to verify as either VISA, MASTERCARD or AMEX. Otherwise the output should be INVALID.
The verification should work like this:
4 0 0 3 6 0 0 0 0 0 0 0 0 0 1 4
every second digit, starting from the second to last digit (the bold ones), is multiplied by 2 and added together. If however the multiplied digit has 2 digits, those two digits are added seperatly like:
2 * 6 = 12 so twelve will be 1 + 2
after that you take the other half of the digits (without multiplying them) and add them together so in the end you have something like
8 + 0 + 1 + 2 + 0 + 0 + 0 + 0 + 2 = 13 (for the digits displayed in bold)
and
0 + 3 + 0 + 0 + 0 + 0 + 0 + 4 = 7 (for the other half of the digits)
You add both together to get 20 (which in the problem set is called the checksum. If the last digit of the calculated number is a 0 the card is valid and after that you just have to check some conditions to tell if its an AMEX, VISA or MASTERCARD.
Conditions for the different creditcards:
American Express = 15 Digits, starting with 34 or 37
VISA = 13 or 16 Digits, starting with 4
MasterCard = 16 Digits, starting with 51, 52, 53, 54 or 55
(Sorry for the long introduction)
I tried to make a formular for this calculation but for some reason it doesn't work for all of the numbers we get to test it. I tried a lot of things to change the calculation and the conditions at the end of my code but everytime i fix one problem, another one appears and right now it feels like i thought myself into a rabbit hole so maybe i'm just too blind to see the obvious.
We only use the libraries <stdio.h> - <cs50.h> - <math.h> so far.
long checkcredit = store;
int sum1 = 0;
int sum2;
for (int duo = 0; checkcredit > 0; duo++, checkcredit /= 10)
{
if (duo % 2 == 0)
{
sum1 += (checkcredit % 10);
}
else
{
sum2 = (checkcredit % 10) * 2;
if (sum2 >10)
{
sum2 = (checkcredit % 10) + 1;
}
}
}
sum1 +=sum2;
sum1 = sum1 % 10;
This is the part in which i think the problem is since i printed out the sum1 (the calculated verification number of the long digit) and it sometimes has the wrong output.
store is the original value of the creditcard number (for example 4003600000000014)
checkcredit is just a duplication of store to work with without changing the original store value
sum1 is for the number is displayed in bold (the once that get multiplied by 2 before adding)
sum2 is for the other half of the number
duo is a digit counter for the calculation to see if i the current digit is multiplied or not (thanks to a coworker of mine who gave the hint that i could try it that way, my old version was like 4 times longer
in the end i just add sum1 and sum2 together to get the "Checksum"
There is no compiler error whatsoever, just the Check50 output
Results for cs50/problems/2021/x/credit generated by check50 v3.2.2
:) credit.c exists
:) credit.c compiles
:( identifies 378282246310005 as AMEX expected "AMEX\n", not "INVALID\n"
:( identifies 371449635398431 as AMEX expected "AMEX\n", not "INVALID\n"
:( identifies 5555555555554444 as MASTERCARD expected "MASTERCARD\n", not "INVALID\n"
:( identifies 5105105105105100 as MASTERCARD expected "MASTERCARD\n", not "INVALID\n"
:( identifies 4111111111111111 as VISA expected "VISA\n", not "INVALID\n"
:( identifies 4012888888881881 as VISA expected "VISA\n", not "INVALID\n"
:) identifies 4222222222222 as VISA
:) identifies 1234567890 as INVALID
:) identifies 369421438430814 as INVALID
:) identifies 4062901840 as INVALID
:) identifies 5673598276138003 as INVALID
:) identifies 4111111111111113 as INVALID
:) identifies 4222222222223 as INVALID
like i said i think that the error i made is in this part of the code (i even think it has something to do with the condition in the for loop) but i can't figure out what is wrong there.
Just in case the whole code is here:
#include<cs50.h>
#include<stdio.h>
#include<math.h>
int main(void)
{
//Ask user for credit card number
long store;
do
{
store = get_long("Number: ");
}
while (store < 0);
//calculating the amount of digits
long cnumber = store;
int digits;
for (digits = 0 ; cnumber > 0 ; digits++)
{
cnumber/=10;
}
//calculating the checksum
long checkcredit = store;
int sum1 = 0;
int sum2;
for (int duo = 0; checkcredit > 0; duo++, checkcredit /= 10)
{
if (duo % 2 == 0)
{
sum1 += (checkcredit % 10);
}
else
{
sum2 = (checkcredit % 10) * 2;
if (sum2 >10)
{
sum2 = (checkcredit % 10) + 1;
}
//sum1 += sum2;
}
}
sum1 +=sum2;
//printf("%i ", sum1);
sum1 = sum1 % 10;
//conditions for varification of the card
if (sum1 == 0)
{
if (digits != 13 && digits != 15 && digits != 16)
{
printf("INVALID\n");
}
else if (digits == 16 || digits == 13)
{
if (digits == 16 && (store >= 51e14 && store <56e14))
{
printf("MASTERCARD\n");
}
else if ((digits == 13 || digits == 16) && ((store <= 4e13 && store < 5e13)||(store >= 4e15 && store < 5e15)))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
else if (digits == 15)
{
if((store >= 34e13 && store < 35e13)||(store >= 37e13 && store < 38e13))
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
}
}
}
else
{
printf("INVALID\n");
}
}
Please ignore the conditions part at the end, i just prototyped it together to check if it works (which it does if i ignore the checksum condition)
I'm sorry for the long post and i am really thankful for everyone who takes the time to look over this and help a beginner to learn from his mistakes.
-Wannabree
The handling of sum2
is wrong in that it does not sum up something, but overwrites sum2
each time. A possible remedy is to initialize int sum2 = 0;
and change
{
sum2 = (checkcredit % 10) * 2;
if (sum2 >10)
{
sum2 = (checkcredit % 10) + 1;
}
}
to
sum2 += "\0\2\4\6\x8\1\3\5\7\x9"[checkcredit % 10];