CS50 Week1: credit task improvements? - c

First up: i got no prior coding experience and took nearly the whole day to do this task with only the tools they gave us in the first week.
I actually managed to do it, but the code looks not pretty and i want to see if i can improve it somehow?
How could i make the Luhn-algorithm more elegant or the boolean logic at the end (see the Mastercard OR orgy) ?
I would appreciate any help :)
#include <stdio.h>
#include <cs50.h>
int main(void)
{
long num = get_long("Number: ");
int sum_eo, sum_no;
// determine length of input
int length = 0;
for (long i = 1; i < num; i *= 10)
{
length++;
}
// determine the first two numbers of the input
long start_digits = num;
for (int i = 0; i < (length - 2); i++)
{
start_digits /= 10;
}
// Luhn-algorithm
// first every other number from the back
for (long i = 100; i < (num * 10); i = i*100)
{
int every_other = (((num % i)- (num % (i / 10))) / (i/10));
if ((every_other * 2) < 10)
{
sum_eo = sum_eo + (every_other * 2);
}
else
{
sum_eo = sum_eo + 1 + ((every_other*2) % 10);
}
}
// then the other numbers
for (long i = 10; i < (num * 10); i = i*100)
{
int every_no = (((num % i)- (num % (i / 10))) / (i/10));
sum_no = sum_no + every_no;
}
//calculate checksum and choose which card
int checksum = (sum_eo + sum_no) % 10;
if (checksum == 0) //
{
if (length == 15 && (start_digits == 34 || start_digits == 37))
{
printf("AMEX\n");
}
else if ((length == 13 || length == 16) && (start_digits / 10) == 4)
{
printf("VISA\n");
}
else if (length == 16 && (start_digits == 51 || start_digits == 52 || start_digits == 53 || start_digits == 54 || start_digits == 55))
{
printf("MASTERCARD\n");
}
else
printf("INVALID\n");
}
else
printf("INVALID\n");
}

One potential change that you can make is here:
else if (length == 16 && (start_digits == 51 || start_digits == 52 || start_digits == 53 || start_digits == 54 || start_digits == 55))
you can instead do this:
else if (length == 16 && (start_digits >= 51 && start_digits <= 55))

Related

How can I fix the error : Floating point exception (core dumped) in my program?

Several weeks ago, I started to do the CS50 course on EdX to learn a little bit about Computer Science then I started to code in C, so if the program that follows is not really well made, that’s normal.
So basically, when I try to run my program, I get the error message : Floating point exception (core dumped). By looking on the Internet, I understood that it means that there is some expression dividing value by zero in my program, but I cannot figure out where the error comes from. So, please help. And thank you very much in advance for your response.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
//Prompt for input
long cardNum = get_long("Enter your card number : ");
//Calculate the checksum
int totalneedx2 = 0;
int total;
int needx2;
for (int n = 100; n < cardNum; n = n * 100)
{
needx2 = cardNum % n / n * 10;
if (needx2 >= 5)
{
int unit;
needx2 = needx2 * 2;
unit = needx2 % 10;
needx2 = needx2 / 10;
total = needx2 + unit;
}
else if (needx2 < 5)
{
needx2 = needx2 * 2;
total = needx2;
}
totalneedx2 = total + totalneedx2;
needx2 = 0;
}
int nox2;
int totalnox2 = 0;
for (int n = 10; n < cardNum; n = n * 100)
{
nox2 = cardNum % n / n * 10;
totalnox2 = totalnox2 + nox2;
nox2 = 0;
}
int totalChecksum = totalnox2 + totalneedx2;
if (totalChecksum % 10 == 0)
{
if (cardNum >= 1000000000000)
{
if (cardNum / 1000000000000 == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
else if (cardNum >= 100000000000000)
{
if (cardNum / 10000000000000 == 34 || cardNum / 10000000000000 == 37)
{
printf("AMEX/n");
}
else
{
printf("INVALID\n");
}
}
else if (cardNum >= 1000000000000000)
{
if (cardNum / 100000000000000 == 51 || cardNum / 100000000000000 == 52 || cardNum / 100000000000000 == 53 || cardNum / 100000000000000 == 54 || cardNum / 100000000000000 == 55)
{
printf ("MASTERCARD\n");
}
else if (cardNum / 1000000000000000 == 4)
{
printf ("VISA\n");
}
else
{
printf("INVALID\n");
}
}
}
else
{
printf("INVALID\n");
}
}

cs50: pset1: credit: Stuck, all cards entered invalid

Been working on this problem set for the past few hours and I thought I was doing pretty well, but when I ran it, doesn't really work as expected.
Kinda stuck at the moment, can anyone offer some insight?
EDIT
Sorry guys, I'll provide a little more insight on the problem because too little info is provided for it in my post. So basically I have to implement the Luhn's algorithm. According to Luhn’s algorithm, you can determine if a credit card number is (syntactically) valid as follows:
Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
Add the sum to the sum of the digits that weren’t multiplied by 2.
If the total’s last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];
int n = strlen(ccnum);
for (int i = 0; i<16; i++)
{
ccnumber[i] = ccnum[i] -'0';
}
int ccnumber_m[7];
for (int i = 0; i < 16; i+=2)
{
ccnumber_m[i] = ccnumber[i]*2;
}
int sum = 0;
for (int i = 0; i < 8; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
printf("%d\n", sum);
}
for (int i = 1; i < 16; i+=2)
{
sum += ccnumber[i];
}
if (sum%10 == 0)
{
if ( (n == 15) && (ccnumber[0] == 34 || ccnumber[0] == 37))
{
printf("AMEX\n");
}
else if ((n == 16) && (ccnumber[0] == 51 || ccnumber[0] == 52 ||ccnumber[0] == 53 || ccnumber[0] == 54 || ccnumber[0] == 55))
{
printf("MASTERCARD\n");
}
else if ((n == 13 || n == 16) && ccnumber[0] == 4)
{
printf("VISA\n");
}
}
else
{
printf("INVALID\n");
}
}
I've added a printf to my sum variable to see where the program is failing and that's where things seem to be screwing up. Every time I run it, different values of sum appear?!
Thanks in advance.
Okay guys, found the solution. Yes I messed up most of my loops and the array ranges and the conditions were all over the place. Did some tweaks to my code overall and after a few more hours, the code works as expected. Here's the updated code.
Pretty sure the code could be more succinct and could be solved much faster. Will take a look at it tomorrow again in order to brainstorm more ideas and find ways to solve it faster.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];
int n = strlen(ccnum);
int counter = 0;
for (int i = 0; i < n; i++)
{
ccnumber[i] = ccnum[i] -'0';
if (ccnumber[i] >= 0)
{
counter ++;
}
}
int sum = 0;
if (counter == 16)
{
int ccnumber_m[7];
int index = 0;
for (int i = counter - 2; i > -1 ; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 8; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 1; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else if (counter == 15)
{
int ccnumber_m[6];
int index = 0;
for (int i = counter-2; i > 0; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 7; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 0; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else if(counter == 13)
{
int ccnumber_m[5];
int index = 0;
for (int i = counter-2; i > 0; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 6; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 0; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else
{
printf("INVALID\n");
return 0;
}
if (sum%10 == 0)
{
if ((counter == 15) && ((ccnumber[0] == 3 && ccnumber[1] == 4) || (ccnumber[0] == 3 && ccnumber[1] == 7)))
{
printf("AMEX\n");
}
else if ((counter == 16) && ((ccnumber[0] == 5 && ccnumber[1] == 1) || (ccnumber[0] == 5 && ccnumber[1] == 2) || (ccnumber[0] == 5 && ccnumber[1] == 3) || (ccnumber[0] == 5 && ccnumber[1] == 4) || (ccnumber[0] == 5 && ccnumber[1] == 5)))
{
printf("MASTERCARD\n");
}
else if ((counter == 13 || counter == 16) && (ccnumber[0] == 4))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
else
{
printf("INVALID\n");
return 0;
}
}

CS50 Credit Problem is skipping "else if" part

I am really stuck here. The programm gives right answer to invald credit card numbers but never say if its VISA, AMEX or MASTERCARD.
I need to post the complete code because I do not have so much experience wit the C language.
The checksum part in the end could also have been "bool" but I always got error messages with that.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long long card;
int checksum = 0;
do
{
card = get_long_long("Number: ");
}while (card <= 0);
int count = 0;
while (card != 0) {
card /= 10; // n = n/10
++count;
}
if(count != 16 && count != 13 && count != 15){
printf("INVALID\n");
}
else if(checksum != 0){
printf("INVALID\n");
}
else if(card >= 34e13 || card >= 37e13){
printf("AMEX\n");
}
else if(card >= 51e14 || card >= 52e14 || card >= 53e14 || card >= 54e14 || card >= 55e15) {
printf("MASTERCARD\n");
}
else if(card >= 4e15 || card >=4e12) {
printf("VISA\n");
}
else {
printf("INVALID\n");
}
}
int checksum(long long card_nr)
{
int sum = 0;
for (int i=0;card_nr !=0; i++, card_nr/=10 )
{
if(i % 2 == 0)
sum += card_nr % 10;
else
{
int digit = 2 * (card_nr % 10);
sum += digit / 10 + digit % 10;
}
}
return (sum % 10) == 0;
}
There may be major issue or only some parenthesis, the programm is compiling. Thanks for any help.
There are many errors with the logic:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long long card;
int checksum = 0;
do
{
card = get_long_long("Number: ");
}while (card <= 0);
int count = 0;
// ** In here you destroy card, so later card whill allways be 0
while (card != 0) {
card /= 10; // n = n/10
++count;
}
if(count != 16 && count != 13 && count != 15){
printf("INVALID\n");
}
else if(checksum != 0){
printf("INVALID\n");
}
//** here it is the same as if(card >= 34e13)
else if(card >= 34e13 || card >= 37e13){
printf("AMEX\n");
}
//** here it is the same as if(card >= 51e14)
//** also these values are already covered by last check
else if(card >= 51e14 || card >= 52e14 || card >= 53e14 || card >= 54e14 || card >= 55e15) {
printf("MASTERCARD\n");
}
//** here it is the same as if(card >= 4e15)
//** also these values are already covered by previous check
else if(card >= 4e15 || card >=4e12) {
printf("VISA\n");
}
else {
printf("INVALID\n");
}
}
int checksum(long long card_nr)
{
int sum = 0;
for (int i=0;card_nr !=0; i++, card_nr/=10 )
{
if(i % 2 == 0)
sum += card_nr % 10;
else
{
int digit = 2 * (card_nr % 10);
sum += digit / 10 + digit % 10;
}
}
return (sum % 10) == 0;
}```
After loop:
while (card != 0) {
card /= 10; // n = n/10
++count;
}
card = 0 and original card number is lost.
You can save original card number to another variable and then compare it.
Also it is better to use integer constants like 54LL << 14 instead of float 54e14

CS50 Luhn's Algorithm in C

I'm new to C and I'm doing CS50. I can't get my code to work. I'm almost positive the for statement is correct. The sum given by the for statement is correct.
I think it's something to do with the (floor(ccNumber / pow(10,13) == 34) in the if statements.
Explanation of Luhn's Algorithm: https://cs50.harvard.edu/x/2020/psets/1/credit/
Sample credit card numbers for testing: https://www.freeformatter.com/credit-card-number-generator-validator.html
#include <stdio.h>
#include <cs50.h>
#include <math.h>
void credit(long ccNumber);
int main(void)
{
long ccNumber = 0;
credit(ccNumber);
}
void credit(long ccNumber)
{
do
{
ccNumber = get_long("Enter a credit card number: ");
}
while (ccNumber < 0);
{
int sum = 0;
long ccNumberFormat = ccNumber;
int nDigits = floor(log10(ccNumberFormat)) + 1;
int parity = nDigits % 2; // if parity % 2 == 0 then even number of digits, otherwise odd number of digits
for (int i = nDigits; i >= 0; i--) {
int digit = ccNumberFormat % 10;
if (i % 2 != parity) { // even number credit card digits will be multiplied by 2 every even number (starting from 0)
digit = digit * 2;
// printf("%d\n", sum);
}
if (digit > 9) {
digit = digit - 9;
}
sum = sum + digit;
ccNumberFormat /= 10;
printf("%d\n", sum);
}
if (sum % 10 == 0 && nDigits == 15 && (floor(ccNumber / pow(10,13) == 34) || (floor(ccNumber / pow(10,13) == 37))))
{
printf("%s\n", "AMEX");
}
else if (sum % 10 == 0 && (nDigits == 13 || nDigits == 16) && (floor(ccNumber / pow(10,12) == 4) || floor(ccNumber / pow(10,15) == 4)))
{
printf("%s\n", "VISA");
}
else if (sum % 10 == 0 && nDigits == 16 && ((floor(ccNumber / pow(10,14) >= 51) || (floor(ccNumber / pow(10,14) <= 55)))))
{
printf("%s\n", "MASTERCARD");
}
}
}
Pseudocode I more or less followed on Wikipedia::
function checkLuhn(string purportedCC) {
int sum := integer(purportedCC[length(purportedCC)-1])
int nDigits := length(purportedCC)
int parity := nDigits modulus 2
for i from 0 to nDigits - 2 {
int digit := integer(purportedCC[i])
if i modulus 2 = parity
digit := digit × 2
if digit > 9
digit := digit - 9
sum := sum + digit
}
return (sum modulus 10) = 0
}
A credit card number is a big number, are you sure long is enough and you do not need long long
Out of that in your expressions like floor(ccNumber / pow(10,13) == 34) the ')' is wrongly placed and you wanted floor(ccNumber / pow(10,13)) == 34 and of course the same for others :
if (sum % 10 == 0 && nDigits == 15 && ((floor(ccNumber / pow(10,13)) == 34) || (floor(ccNumber / pow(10,13)) == 37)))
{
printf("%s\n", "AMEX");
}
else if (sum % 10 == 0 && (nDigits == 13 || nDigits == 16) &&((floor(ccNumber / pow(10,12)) == 4) || (floor(ccNumber / pow(10,15)) == 4)))
{
printf("%s\n", "VISA");
}
else if (sum % 10 == 0 && nDigits == 16 && ((floor(ccNumber / pow(10,14)) >= 51) || (floor(ccNumber / pow(10,14)) <= 55)))
{
printf("%s\n", "MASTERCARD");
}
but in
else if (sum % 10 == 0 && (nDigits == 13 || nDigits == 16) &&((floor(ccNumber / pow(10,12)) == 4) || (floor(ccNumber / pow(10,15)) == 4)))
you take the risk to have a bad result, you need to check (floor(ccNumber / pow(10,12)) == 4) only if nDigits == 13 and (floor(ccNumber / pow(10,15)) == 4) only if nDigits == 16 and you can simplify to have :
else if (sum % 10 == 0 && (nDigits == 13 || nDigits == 16) &&(floor(ccNumber / pow(10,nDigits-1)) == 4))
So finally :
#include <stdio.h>
#include <math.h>
void credit(long long ccNumber);
int main(void)
{
long long cc[] = { 4532057997187363ll, // visa
4485661945778178ll, // visa
2720995573736457ll, // MasterCard
2720998284576493ll, // MasterCard
375137447049450ll, // amex
378572901284556ll, // amex
};
for (int i = 0; i != sizeof(cc)/sizeof(*cc); ++i)
credit(cc[i]);
return 0;
}
void credit(long long ccNumber)
{
int sum = 0;
long long ccNumberFormat = ccNumber;
int nDigits = floor(log10(ccNumberFormat)) + 1;
int parity = nDigits % 2; // if parity % 2 == 0 then even number of digits, otherwise odd number of digits
for (int i = nDigits; i >= 0; i--) {
int digit = ccNumberFormat % 10;
if (i % 2 != parity) { // even number credit card digits will be multiplied by 2 every even number (starting from 0)
digit = digit * 2;
// printf("%d\n", sum);
}
if (digit > 9) {
digit = digit - 9;
}
sum = sum + digit;
ccNumberFormat /= 10;
//printf("%d\n", sum);
}
if (sum % 10 == 0 && nDigits == 15 && ((floor(ccNumber / pow(10,13)) == 34) || (floor(ccNumber / pow(10,13)) == 37))) {
printf("%lld %s\n", ccNumber, "AMEX");
}
else if (sum % 10 == 0 && (nDigits == 13 || nDigits == 16) &&(floor(ccNumber / pow(10,nDigits-1)) == 4)) {
printf("%lld %s\n", ccNumber, "VISA");
}
else if (sum % 10 == 0 && nDigits == 16 && ((floor(ccNumber / pow(10,14)) >= 51) || (floor(ccNumber / pow(10,14)) <= 55))) {
printf("%lld %s\n", ccNumber, "MASTERCARD");
}
}
Compilation and execution:
pi#raspberrypi:/tmp $ gcc -Wall f.c -lm
pi#raspberrypi:/tmp $ ./a.out
4532057997187363 VISA
4485661945778178 VISA
2720995573736457 MASTERCARD
2720998284576493 MASTERCARD
375137447049450 AMEX
378572901284556 AMEX
pi#raspberrypi:/tmp $
note also to do floating point computation is a risk, you can do all only using long long
regarding:
int main(void)
{
long ccNumber = 0;
credit(ccNumber);
}
void credit(long ccNumber)
{
do
{
ccNumber = get_long("Enter a credit card number: ");
}
The call to credit() is passing the contents of the variable: ccnumber rather than a pointer to ccnumber. So the called function: credit() can never change that value in main().
Suggest:
int main(void)
{
long ccNumber = 0;
credit( &ccNumber );
}
void credit(long * ccNumber)
{
do
{
*ccNumber = get_long("Enter a credit card number: ");
}
In general, should never compare a floating point value with an integer value for equality, So the following kind of expression is very unreliable:
(floor(ccNumber / pow(10,13) == 34)
also, such an expression is actually just comparing two digits of the ccnumber to 34. MUCH better to have read the credit card number as a string then comparing the two digits to ccnumber[ first digit position ] == 3 && ccnumber[ second digit position ] == 4. Similar considerations exist for all the other expressions that are using pow()
Therefore, suggest getting the credit card number via:
string ccnumber = get_string( "enter credit card number" );
the result will be a pointer to the string containing the credit card number. each of the 'interesting' digits can then be accessed as an index (starting with 0) into the credit card number
however, if you really do not want to use a char array, you could replace expressions like;
(floor(ccNumber / pow(10,13) == 34)
with:
(ccNumber / 10000000000000 == 34)
#include <stdio.h>
#include <cs50.h>
// Luhn's Algorithm
int main(void)
{
long cardNumber = get_long("Please, enter your card number: ");
int sum1 = 0, num = 0, remainder = 0, sum2 = 0;
long temp = cardNumber;
while (temp > 0)
{
num = ((temp / 10) % 10) * 2; // Multiplying every other digit by 2, starting with the number’s second-to-last digit
while (num > 0)
{
remainder = num % 10;
sum1 += remainder; // Adding those products’ digits together
num /= 10;
}
temp /= 100;
}
// So as to restore the initial values of remainder and temp for the use in next loop
remainder = 0;
temp = cardNumber;
while (temp > 0)
{
remainder = temp % 10;
sum2 += remainder; // Sum of the digits that weren’t multiplied by 2
temp /= 100;
}
((sum1 + sum2) % 10) == 0 ? printf("Valid\n") : printf("Invalid\n");
return 0;
}
Solution based on concepts explained in week 1
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long long cardNum;
do
{
cardNum = get_long_long("Enter Card number: ");
}
while (cardNum < 1);
long long tempCC;
int remNum, sum = 0, sum1 = 0, counter = 1, currentNum, total;
tempCC = cardNum;
do
{
currentNum = tempCC % 10;
if (counter % 2 == 0)
{
currentNum = currentNum * 2;
if (currentNum > 9)
{
currentNum = currentNum - 9;
}
sum += currentNum;
}
else
{
sum1 += currentNum;
}
counter++;
tempCC = tempCC / 10;
}
while (tempCC > 0);
total = sum + sum1;
if (total % 10 == 0)
{
tempCC = cardNum;
do
{
tempCC = tempCC / 10;
}
while (tempCC < 10 || tempCC > 100);
if (((counter - 1) == 15) && (tempCC == 34 || tempCC == 37))
{
printf("AMEX\n");
}
else if (((counter - 1) == 16) && (tempCC >= 51 && tempCC <= 55))
{
printf("MASTERCARD\n");
}
else if ((((counter - 1) == 13) || ((counter - 1) == 16)) && (tempCC / 10 == 4))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
else
{
printf("INVALID\n");
}
}

CS50 Credit, loop if not card number

I have nearly finished the Credit task of PSET1 (CS50) although I have run into a problem trying to get the program to not allow an entry that isn't a card number (E.g "Foo" or "t" or anything other than a number) and then loop.
I have attempted various while statements and goto statements although none of these attempts have been sucessful
Also any other suggestions would be appreciated.
#include <stdio.h>
#include <cs50.h>
int main(void)
{
//gets cardnumber & counts digits entered
long long cardnumber;
int count = 0;
{
//prompts user for a cardnumber
printf("Enter a cardnumber: ");
scanf("%lld", &cardnumber);
}
//Prints count of digits entered (will likely not need this part)
//else printf("Number of digits: %d", count); printf("\n");
//Finds first 8 digits for checksum)
int digit1 = (((cardnumber % 100) / 10) * 2);
int digit2 = (((cardnumber % 10000) / 1000) * 2);
int digit3 = (((cardnumber % 1000000) / 100000) * 2);
int digit4 = (((cardnumber % 100000000) / 10000000) * 2);
int digit5 = (((cardnumber % 10000000000) / 1000000000) * 2);
int digit6 = (((cardnumber % 1000000000000) / 100000000000) * 2);
int digit7 = (((cardnumber % 100000000000000) / 10000000000000) * 2);
int digit8 = (((cardnumber % 10000000000000000) / 1000000000000000) * 2);
//Sum first 8 digits of checksum
int check1 = ((digit1 % 10) + (digit1 / 10));
check1 = (check1 + (digit2 % 10)) + (digit2 / 10);
check1 = (check1 + (digit3 % 10)) + (digit3 / 10);
check1 = (check1 + (digit4 % 10)) + (digit4 / 10);
check1 = (check1 + (digit5 % 10)) + (digit5 / 10);
check1 = (check1 + (digit6 % 10)) + (digit6 / 10);
check1 = (check1 + (digit7 % 10)) + (digit7 / 10);
check1 = (check1 + (digit8 % 10)) + (digit8 / 10);
//Sum last 8 digits of checksum & Sum of first 8 (check1)
int digit9 = ((cardnumber % 10) / 1);
int digit10 = ((cardnumber % 1000) / 100);
int digit11 = ((cardnumber % 100000) / 10000);
int digit12 = ((cardnumber % 10000000) / 1000000);
int digit13 = ((cardnumber % 1000000000) / 100000000);
int digit14 = ((cardnumber % 100000000000) / 10000000000);
int digit15 = ((cardnumber % 10000000000000) / 1000000000000);
int digit16 = ((cardnumber % 1000000000000000) / 100000000000000);
//add to remaining digits to those that were multiplied by 2
int checksum = (check1 + digit9 + digit10 + digit11 + digit12 + digit13 + digit14 + digit15 + digit16);
// Check first 2 digits
if (cardnumber / 10000000000000 == 34 || cardnumber / 10000000000000 == 37 )
goto Amex;
if (cardnumber / 100000000000000 == 51 || cardnumber / 100000000000000 == 52 || cardnumber / 100000000000000 == 53 || cardnumber / 100000000000000 == 54 || cardnumber / 100000000000000 == 55 )
goto Master;
if (cardnumber / 1000000000000000 == 4 )
goto Visa;
else
{
printf("INVALID\n");
(I = 0);
}
goto End;
// Amex start with 34 or 37
Amex:;
char A;
if (cardnumber / 10000000000000 == 34 || cardnumber / 10000000000000 == 37 )
{
A = 1;
}
else
{
A = 0;
}
goto End;
// Mastercard start with 51, 52, 53, 54, 55
Master:;
char M;
if (cardnumber / 100000000000000 == 51 || cardnumber / 100000000000000 == 52 || cardnumber / 100000000000000 == 53 || cardnumber / 100000000000000 == 54 || cardnumber / 100000000000000 == 55 )
{
M = 1;
}
else
{
M = 0;
}
goto End;
//Visa start with 4
Visa:;
char V;
if (cardnumber / 1000000000000000 == 4 )
{
V = 1;
}
else
{
V = 0;
}
goto End;
End:;
while(cardnumber != 0)
{
// cardnumber = cardnumber/10
cardnumber /= 10;
++count;
}
// if cardnumber <13 or >16 digits error "invalid card" given
if (count > 16 || count < 13)
{
printf("INVALID\n");
(I = 0);
}
// Keep track of first 2 digits & validate checksum
char T;
if (checksum % 10 == 0)
{
T = 1;
}
else
{
T = 0;
}
if (T == 0) printf("INVALID\n");
{
(I = 0);
}
// - Amex (15 digits, start with 34 or 37)
if (count == 15 && T == 1 && A == 1)
{
printf("AMEX\n");
}
// - Mastercard (16 digits, start with 51, 52, 53, 54, 55)
if (count == 16 && T == 1 && M == 1)
{
printf("MASTERCARD\n");
}
// - Visa (13 & 16 digits, start with 4)
if ((count == 13 && T == 1 && V == 1) || (count == 16 && T == 1 && V == 1))
{
printf("VISA\n");
}
}
Prompt the user to type in the credit card number, use a do while loop so that if the number is less than 0, you will keep asking the user for a card number.
int main(void)
{
long long credit_card_number;
do
{
credit_card_number = get_long_long("Enter Valid Credit Card Number: ");
}
while (credit_card_number < 0);
#include <cs50.h>
#include <math.h>
#include <stdio.h>
int main(void)
{
long long cardnumber = 0;
do
{
cardnumber = get_long("Number: ");
}
while (cardnumber < 0);
int count = 0;
long long digits = cardnumber;
while (digits > 0)
{
digits = digits/10;
count++;
}
if ((count != 13) && (count != 15) && (count != 16))
{
printf("INVALID\n");
}
int number[count];
for (int i = 0; i < count; i++)
{
number[i] = cardnumber % 10;
cardnumber = cardnumber / 10;
}
int originalnumber[count];
for (int i = 1; i < count; i++)
{
originalnumber[i] = number[i];
}
for (int i = 1; i < count; i+=2)
{
number[i] = number[i] * 2;
}
int v = 0;
int temp;
if (count == 13)
{
for (int i = 0; i < count; i++)
{
temp = (number[i] % 10) + (number[i]/10 % 10);
v = v + temp;
}
if (originalnumber[12] == 4 && v % 10 == 0)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
if (count == 15)
{
for (int i = 0; i < count; i++)
{
temp = (number[i] % 10) + (number[i]/10 % 10);
v = v + temp;
}
if (originalnumber[14] == 3 && v % 10 == 0 && (originalnumber[13] == 4 || originalnumber[13] == 7))
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
}
}
if (count == 16)
{
for (int i = 0; i < count; i++)
{
temp = (number[i] % 10) + (number[i]/10 % 10);
v = v + temp;
}
if (originalnumber[15] == 4 && v % 10 == 0)
{
printf("VISA\n");
}
else if (originalnumber[15] == 5 && v % 10 == 0 && (originalnumber[14] == 1 || originalnumber[14] == 2 || originalnumber[14] == 3 || originalnumber[14] == 4 || originalnumber[14] == 5))
{
printf("MASTERCARD\n");
}
else
{
printf("INVALID\n");
}
}
}

Resources