PSET 01, CS50x (Credit); My program is not printing the card names

46 Views Asked by At

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;
                   ^~~~~~~~~~~~~~~
1

There are 1 best solutions below

0
Chris On

An int isn'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.