Below is some code which verifies a credit card number using the checksum as well as check if number of digits are appropriate as well if digits start with right numbers. I am not sure if converting the double
into a string was the best bet. I wasn't going to at first but had trouble figuring out the modulo math to get every second digit without knowing the length of the double
(# of digits).
Also, in my use of strtok()
, what should I be doing with the balance of the string after the delimiter? Is that hanging out in memory somewhere?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
double cardnumber;
printf("Give me a number: \n");
scanf("%lf", &cardnumber);
if(cardnumber < 1000000000000 || cardnumber > 10000000000000000)
{
printf("INVALID\n");
return 0;
}
if(cardnumber < 100000000000000 && cardnumber > 9999999999999)
{
printf("INVALID\n");
return 0;
}
char creditcard[17];
sprintf(creditcard, "%f", cardnumber);
char* ptr_cc;
ptr_cc = strtok(creditcard,".");
int card_size = strlen(ptr_cc);
int sum = 0;
for(int i = 1; i < card_size; i+=2)
{
int x = creditcard[card_size-1-i] - '0';
int prod = 2 * x;
if(prod>=10)
{
prod = prod%10 + prod/prod%10;
}
sum += prod;
}
for(int i = 0; i < card_size; i+=2)
{
int x = creditcard[card_size-1-i] - '0';
sum += x;
}
if(sum%10 != 0)
{
printf("INVALID\n");
return 0;
}
else if(creditcard[0] == '4')
{
printf("VISA\n");
return 0;
}
else if(creditcard[0] == '3' && (creditcard[1] == '7' || creditcard[1] =='4'))
{
printf("AMEX\n");
return 0;
}
else if(creditcard[0] == '5' && (creditcard[1] >='1' && creditcard[1] <='5'))
{
printf("MASTERCARD\n");
return 0;
}
else
{
printf("INVALID\n");
return 0;
}
}
number
in adouble
in the first place. The cardnumber
is really a digit string; note that the format technically allows a leading digit of0
. [ Wikipedia]. [Another example of a number that isn't is a 'phone number'.] Using a string has the natural benefit that you can allow the I/O to have internal spaces as well - making it much more usable. \$\endgroup\$