1

I have no experience programming, and English is not my first language so I'm struggling a lot with this particular problem.

In "credit.c" you have to prompt the user for a credit card number and then check if it is invalid. If it is not, you have to provide the brand of the credit card.

I conceptually understand what I have to do, and tried to do it. First I established the number of digits in the credit card (I divided the number "n" times till the result was 0). Immediatly after that I render invalid any credit number with digits different of 13, 15 or 16.

Then I start storing the numbers of the credit card individually in an Array. Then I create an array with the "second to last" and every 2 other number (those are the ones you need to multiply times 2) Then I consider the posibility of having a resulting number greater than 9. Then I create a third array with the other numbers. Then I add the numbers and see if that addition ends in "0". If that is correct, I just check the condition of the brands (number or digits plus beggining numbers of the credit card).

Problem is the program outputs "INVALID" for every number. It says something about overflowing an integer so I imagine I messed up around the lines 30 to 40 when I go from long long to int.

Any help would be highly appreciated! This is my code

#include <stdio.h>
#include <cs50.h>
#include <string.h>

int main(void)
{
/* I prompt the user for a long long number */
long long numero = 0;
int contar = 0;

printf("Please type credit card number: ");
numero = get_long_long();

/* I check the number of digits by dividing by 10 till result is 0 */
while (numero != 0)
{
  numero /= 10;
  ++contar;
}
/* If the number of digits is different than 13, 15 or 16 I know the credit card is invalid */
if (contar != 13 && contar != 15 && contar != 16)
{
printf("INVALID\n");
    return 0;
}
/* I will create arrays to store the numbers I need. Will start with all the numbers */
int MiArray[contar];
long long temporal = numero;
int i = 0;

while (temporal != 0)
{
    MiArray[contar - 1 - i] = temporal % 10;
}
temporal = temporal / 10;
i++;

/* Now I create the Array of the numbers I will have to multiply by 2 after */
int ArrayDeCalculo[contar / 2];
int m = 2;
int l = 0;

while ((contar - m) > -1)
{
    ArrayDeCalculo[l] = 2 * MiArray[contar - m];
    m = m + 2;
    l++;
}
/* Here I tell the program to analyze the result of 2*every other digit and either store it or add both digits and then store it */
int DobleDigito = 0;
for (int j = 0; j < contar / 2; j++)
{
    if (ArrayDeCalculo[j] > 9)
    {
        int PrimerDigito = 0;
        DobleDigito = DobleDigito + (ArrayDeCalculo[j] % 10);
        PrimerDigito = ArrayDeCalculo[j] / 10;
        DobleDigito = DobleDigito + PrimerDigito;
    }
    else
    {
        DobleDigito = DobleDigito + ArrayDeCalculo[j];
    }
     /* Now I create the 3rd array for the numbers I haven't stored in the second array */
    int TercerArray[contar - (contar / 2)];
    int p = 1;
    int r = 0;

    while ((contar - p) > -1)
    {
        TercerArray[r] = MiArray[contar - p];
        p = p + 2;
        r++;
    }
    int OtroDigito = 0;

    for (int w = 0; w < (contar - (contar/2)); w++)
    {
        OtroDigito = OtroDigito + TercerArray[w];
    }
     /* Now I declare the variables that will use to recover the first two digits of the original credit card (stored in the first array) */
    int PrimerNumero;
    int SegundoNumero;

     /* Here I check Luhn's algorhitm */
    if ((DobleDigito + OtroDigito) % 10 == 0)
    {
        PrimerNumero = MiArray[0];
        SegundoNumero = MiArray[1];
    }
    else
    {
  printf("INVALID\n");
    }
    return 0;
    /* Here I check the conditions of every brand*/
    if (contar == 15 && PrimerNumero == 3 && (SegundoNumero == 4 || SegundoNumero == 7))
    {
    printf("AMEX\n");
    }
    else if (contar == 16 && PrimerNumero == 5 && (SegundoNumero >0 && SegundoNumero <6))
    {
        printf("MASTERCARD\n");
    }
    else if ((contar == 13 || contar == 16) && PrimerNumero == 4)
    {
    printf("VISA\n");
    }
    else
    {
    printf("INVALID\n");
    }
    return 0;
}

2 Answers 2

2

Your counting loop destroys the number. Destroy a copy instead.

And stack variables are not initialised by default, so you end up with some arbitrary data as the array isn't filled at all due to your first mistake.

While the use of one array for all the digits might be reasonable, the use of extra arrays is definitely not required. You can process one digit at a time, and keep only the sum. That's where I no longer understand your code (the mix of English/Spanish doesn't help either, but the many variables and arrays are just too much, you're clearly overthinking the problem).

1

I got you, man. A little more experience with programming and you'll get there. Try including math.h and using some of its methods for counting and sorting through the digits. Here's my code as an example, if you're still confused. This is beginner level programming but you need a good understanding of the mathematics used to sort numbers. It's not very intuitive in C, and hence a problem like this would be much easier to handle in C++ or Java. Good luck and I hope this helps someone!

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

int calcDigit(long input, int column);
int calcLength(long input);
int sumOfDigits(long input);
long calcEEDig(long input, bool even);
string checkValidity(long input);

int main(void)
{
    long input = get_long("Number: ");
    printf("%s", checkValidity(input));
}

int calcDigit(long input, int column)   // calculates the digit in the current column
{
    long mod = pow(10, column);
    long div = mod / 10;
    return ((input % mod) / div);
}

int calcLength(long input)  // calculates the length of a given input
{
    int length = 1;
    while (input /= 10)
    {
        length++;
    }
    return length;
}

int sumOfDigits(long input) // Adds all the digits of an input and returns the sum
{
    int output = 0;
    for (int i = 1; i <= calcLength(input); i++)
    {
        output = output + calcDigit(input, i);
    }
    return output;
}

long calcEEDig(long input, bool even)
{
    int inputLength = calcLength(input);        // Calculates input length with a functions and sets it to a variable
    int column;
    long eEDig = 0;
    int parity;
    if (even == true)       // If finding every even or odd number
    {
        parity = 1;     // Evens
    }
    else
    {
        parity = 0;     // Odds
    }
    for (int i = parity; i <= inputLength;
         i = i + 2)     // Essentially "highlights" every other digit in the input starting at the second to last digit
    {
        if (i > 1)      // Used to determine which column each digit will be stored in
        {
            column = calcLength(eEDig);    // Stores digits in next column after currently greatest column
        }
        else
        {
            column = 0;                     // Starts storing in the first column if first run
        }
        // Updates eEDig with new digit, its product of 2 if even is true, and sets its column
        eEDig = eEDig + ((calcDigit(input, i + 1)) * (parity + 1)) * pow(10, (column));
        //printf("calcDigit -> Parity: %i -  Digit: %i - Output: %ld\n", parity, calcDigit(input, i + 1), eEDig);
    }
    return eEDig;
}

string checkValidity(long input)
{
    long eEDig1 = calcEEDig(input, true);             // Used to store and manipulate every other digit. Boolean sets desired parity
    long eEDig2 = calcEEDig(input, false);
    if ((sumOfDigits(eEDig1) + sumOfDigits(eEDig2)) % 10 == 0)
    {
        int dig1 = calcDigit(input, calcLength(input));
        int dig2 = calcDigit(input, calcLength(input) - 1);
        int inputLength = calcLength(input);

        if (dig1 == 4)
        {
            if (inputLength == 13 || inputLength == 16)
            {
                return "VISA\n";
            }
        }
        if (dig1 == 3)
        {
            if (dig2 == 4 || dig2 == 7)
            {
                if (inputLength == 15)
                {
                    return "AMEX\n";
                }
            }
        }
        if (dig1 == 5)
        {
            if (dig2 == 1 || dig2 == 2 || dig2 == 3 || dig2 == 4 || dig2 == 5)
            {
                if (inputLength == 16)
                {
                    return "MASTERCARD\n";
                }
            }
        }
    }
    return "INVALID\n";
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .