Reputation:
I wanted to check if a credit card number is valid or not but when i run the code, every number I give as input, the output comes as invalid.
The example given below is what I should i do.
Example with David’s Visa: 4003600000000014.
For the sake of discussion, let’s first underline every other digit, starting with the number’s second-to-last digit:
4003600000000014
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
That gives us:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
#include <stdio.h>
int main()
{
int no;
printf("Visa number: ");`
scanf("%d", &no);
int d_1, d_2, d_3, d_4, d_5, d_6, d_7, d_8, d_9, d_10, d_11, d_12, d_13, d_14, d_15;
d_15 = no%10;
d_14 = ((no%100)/10)*2;
d_13 = (no%1000)/100;
d_12 = ((no%10000)/1000)*2;
d_11 = (no%100000)/10000;
d_10 = ((no%1000000)/100000)*2;
d_9 = (no%10000000)/1000000;
d_8 = ((no%100000000)/10000000)*2;
d_7 = (no%1000000000)/100000000;
d_6 = ((no%10000000000)/1000000000)*2;
d_5 = (no%100000000000)/10000000000;
d_4 = ((no%1000000000000)/100000000000)*2;
d_3 = (no%10000000000000)/1000000000000;
d_2 = ((no%100000000000000)/10000000000000)*2;
d_1 = (no%1000000000000000)/100000000000000;
int d[7] = {d_2, d_4, d_6, d_8, d_10, d_12, d_14};
int n,add;
for (n=1; n<=7; n++)
if(d[n]>10)
{
d[n] = (d[n]%10);
d[(15-n)+1] = ((d[n]%100)/10);
int sum=0;
for (int i=0; i<7; i++)
sum += d[i];
}
else
{
add = d_14 + d_12 + d_10 + d_8 + d_6 + d_4 + d_2;
}
int sum = add + d_15 + d_13 + d_11 + d_9 + d_7 + d_5 + d_3 + d_1;
if ((sum % 10) == 0)
{
printf("%s\n", "The card is valid");
}
else
{
printf("%s\n", "The card is invalid");
}
}
Upvotes: 0
Views: 1592
Reputation: 1
Consider declaring the user input as a long long data type so as to store up to 16 digits.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt for Input
long long n;
do
{
n = get_long_long("Number: ");
}
while (n < 0);
// Calculate Checksum
int l;
int m;
int sum;
long long first = n;
long long first_two = n;
int f = 0;
int p = 0;
int a = 0;
int z = 0;
int y = 0;
int x = 0;
do
{
l = n % 10;
a++;
n = n / 10;
if (a % 2 == 1)
{
z = z + l;
}
if (a % 2 == 0)
{
if ((2 * l) > 9)
{
m = (2 * l) % 10;
f = (2 * l) / 10;
p = p + f + m;
}
else
{
x = x + (2 * l);
}
y = p + x;
}
}
while (n > 0);
sum = z + y; // checksum value
// Check for card length and starting digits
while (first_two > 99)
{
first_two = first_two / 10;
}
while (first > 9)
{
first = first / 10;
}
// Print Card name or Invalid
if ((sum % 10 == 0) && (a == 15) && ((first_two == 34) || (first_two == 37)))
{
printf("AMEX\n");
}
else if ((sum % 10 == 0) && (a == 16) && ((first_two > 50) && (first_two < 56)))
{
printf("MASTERCARD\n");
}
else if ((sum % 10 == 0) && (a == 13 || a == 16) && (first == 4))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
Upvotes: 0
Reputation: 1
#include <stdio.h>
#include <cs50.h>
long credit;
int getting_the_final_total_number (void);
void checking_which_kind (void);
int main(void)
{
credit = get_long("Number: ");
int i = 0;
long number_count = credit;
//finding how many numbers are there.
while(number_count > 0)
{
number_count /= 10;
i++;
}
//we use and because (using or make once true, the code block will work and always telling INVALID)
if(i != 13 && i != 15 && i != 16)
{
printf("INVALID\n");
return 0;
}
int total = getting_the_final_total_number(); //adding sum_1 and sum_2
if(total % 10 != 0)
{
printf("INVALID\n");
return 0;
}
checking_which_kind();
}
//assigning the credit to another variable for the loop
int getting_the_final_total_number (void)
{
long credit_one = credit;
int mod_1;
int mod_2;
int sum_1 = 0;
int m;
int d;
int sum_2 = 0;
do
{
//cutting the number into two pieces with all the last numbers and all the second-last-numbers
//cutting the last numbers.
mod_1 = credit_one % 10;
credit_one = credit_one / 10;
sum_1 += mod_1;
//cutting the second-last-numbers.
mod_2 = credit_one % 10;
credit_one = credit_one / 10;
//doubling the mod_2 (the second-last-numbers)
mod_2 = mod_2 * 2;
//making them into one number (if there is 16 or 18 in the product then make them 1 and 6 or 1 and 8. After that add them all together ).
m = mod_2 % 10; //This is for only one standing numer like 1 or 2 or 9 etc (but no 12 or 14 or 16)
d = mod_2 / 10; //This is for ten's digit to make sure to become ONE standing digit
sum_2 = sum_2 + m + d;
}
while(credit_one > 0);
return sum_1 + sum_2;
}
//checking the first two number of credit
void checking_which_kind (void)
{
long cc = credit;
do
{
cc = cc / 10;
}
while(cc > 100);
if(cc / 10 == 5 && (cc % 10 > 0 || cc % 10 < 6))
{
printf("MASTERCARD\n");
}
else if(cc / 10 == 3 && (cc % 10 == 4 || cc % 10 == 7))
{
printf("AMERICAN EXPRESS\n");
}
else if(cc / 10 == 4 && cc % 10 >= 0)
{
printf("VISA\n");
}
else
{
printf("ERROR");
}
}
Upvotes: 0
Reputation: 154572
every number I give as input, the output comes as invalid.
Too big
OP's int
is likely 32-bit.
Reading text input that would attempt to form an int
outside the int
range is undefined behavior. Rest of code is irrelevant.
int no;
scanf("%d", &no); // attempt to read "4003600000000014" leads to UB.
Consider reading user input into a string first and then process the characters. @Weather Vane
char buf[100];
if (fgets(buf, sizeof buf, stdin)) {
int i;
sum[2] = { 0, 0 }; // sums of even indexed digits and odd indexed digits.
// Note: only 1 sum really needed, but using 2 sums to mimic OP's approach
for (i = 0; isdigit((unsigned char) buf[i]); i++) {
digit = buf[i] - '0';
if (i%2 == 0) {
digit *= 2;
if (digit >= 10) {
digit = (digit/10 + digit%10);
}
}
sum[i%2] += digit;
}
// reject bad input: too long or missing expected end
if (i > 16 || (buf[i] != '\n' && buf[i] != '\0')) {
puts("Bad input");
} else {
// pseudo code to not give everything away.
// do math on sum[0], sum[1]
// if as expected --> success
}
}
Upvotes: 2