I am running the code but whenever i input a legit or correct card no it again prompts me the same print info Card no. but when i input wrong number it gives me "INVALID" which is correct. I just wanna know the answer why my program isn't printing VISA, MASTER, AMEX
#include <stdio.h>
#include "cs50.h"
int main(void)
{
long card;
do
{
card = get_long("Card no: ");
} while (card < 0); // Card number must be greater than 0.
int card1, card2, card3, card4, card5, card6, card7, card8;
card1 = ((card % 100) / 10) * 2;
card2 = ((card % 10000) / 1000 * 2);
card3 = ((card % 1000000) / 100000 * 2);
card4 = ((card % 100000000) / 10000000 * 2);
card5 = ((card % 10000000000) / 1000000000 * 2);
card6 = ((card % 1000000000000) / 100000000000 * 2);
card7 = ((card % 100000000000000) / 10000000000000 * 2);
card8 = ((card % 10000000000000000) / 1000000000000000 * 2);
card1 = (card1 % 100 / 10) + (card1 % 10);
card2 = (card1 % 100 / 10) + (card2 % 10);
card3 = (card1 % 100 / 10) + (card3 % 10);
card4 = (card1 % 100 / 10) + (card4 % 10);
card5 = (card1 % 100 / 10) + (card5 % 10);
card6 = (card1 % 100 / 10) + (card6 % 10);
card7 = (card1 % 100 / 10) + (card7 % 10);
card8 = (card1 % 100 / 10) + (card8 % 10);
int sum1 = card1 + card2 + card3 + card4 + card5 + card6 + card7 + card8;
// Now we need to find the digits that are not multiplied by 2.
int card9, card10, card11, card12, card13, card14, card15, card16;
card9 = (card % 10);
card10 = ((card % 1000) / 100);
card11 = ((card % 100000) / 10000);
card12 = ((card % 10000000) / 1000000);
card13 = ((card % 1000000000) / 100000000);
card14 = ((card % 100000000000) / 10000000000);
card15 = ((card % 10000000000000) / 1000000000000);
card16 = ((card % 1000000000000000) / 100000000000000);
int sum2 = card9 + card10 + card11 + card12 + card13 + card14 + card15 + card16;
int sum3 = sum1 + sum2;
int length = 0;
long visa = card;
long master = card;
long amex = card;
if ((sum3 % 10) != 0)
{
printf("%s\n", "INVALID");
return 0;
}
// Now we need to differentiate between VISA, Master and Amex.
while (card > 0)
{
card = card / 10;
length++;
}
// Identify if the card is VISA.
while (visa >= 10)
{
visa /= 10;
}
if (visa == 4 && (length == 13 || length == 16))
{
printf("%s\n ", "VISA");
return 0;
}
// Identify if the card is AMEX
while (amex >= 10000000000000)
{
amex /= 10000000000000;
}
if (length == 15 && (amex == 34 || amex == 37))
{
printf("%s\n", "AMEX");
return 0;
}
// Identify if the card is MASTER
while (master >= 100000000000000)
{
master /= 100000000000000;
}
if (length == 16 && (master == 51 || master == 52 || master == 53 ||
master == 54 || master == 55 || master == 56))
{
printf("%s\n", "MASTERCARD");
return 0;
}
else
printf("%s\n", "INVALID");
return 0;
}
I think my code is write every time i run my program it prints
Card no. when i type any valid card no it again prompts the same thing i.e Card no. But when i input a wrong number i gives INVALID
I can not figure out why it isn't printing "VISA, MASTER, AMEX"
Similarly when i run my debug it gives this
credit.c: In function 'main':
credit.c:17:13: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card5 = ((card % 10000000000) / 1000000000 * 2);
^
credit.c:18:13: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card6 = ((card % 1000000000000) / 100000000000 * 2);
^
credit.c:19:13: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card7 = ((card % 100000000000000) / 10000000000000 * 2);
^
credit.c:20:13: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card8 = ((card % 10000000000000000) / 1000000000000000 * 2);
^
credit.c:41:14: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card14 = ((card % 100000000000) / 10000000000);
^
credit.c:42:14: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card15 = ((card % 10000000000000) / 1000000000000);
^
credit.c:43:14: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion]
card16 = ((card % 1000000000000000) / 100000000000000);
^
credit.c:77:17: warning: comparison is always false due to limited range of data type [-Wtype-limits]
while (amex >= 10000000000000)
^~
credit.c:79:17: warning: conversion to 'long int' from 'long long int' may alter its value [-Wconversion]
amex /= 10000000000000;
^~~~~~~~~~~~~~
credit.c:88:19: warning: comparison is always false due to limited range of data type [-Wtype-limits]
while (master >= 100000000000000)
^~
credit.c:90:19: warning: conversion to 'long int' from 'long long int' may alter its value [-Wconversion]
master /= 100000000000000;
^~~~~~~~~~~~~~~
An
intisn't large enough to fold a 16 digit number like a credit card. For a 32-bit signed int the max is 2,147,483,647, while for a 64-bit signed int, the max is 9,223,372,036,854,775,807. A 64-bit unsigned int gets you to 18,446,744,073,709,551,615.This disparity in sizes between datatypes is exactly what the warnings are telling you about. If you make it a habit to compile with
-Werror(or equivalent in your compiler) you will be forced to address these issues.A 64-bit int is large enough, but you're better off acknowledging that credit card numbers are not integers at all but rather strings of numeric values.
As a string, it's also easier to iterate through the digits.