0

Im considering skipping :( I dont really understand why it always prints INVALID4....

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

int main (void)
{
    //Initialize a longlong that will hold our creditcard number.
    long long creditcardnumber;

    //Ask the user for the creditcard number, and make sure it is positive.
    do
    {
        printf("Insert your creditcard number, please\n");
        printf("Just digits, thanks\n");
        creditcardnumber = GetLongLong();
    }
    while (creditcardnumber < 0);

    //We know the heights number posissible for any creditcard, if the input number is
    //bigger than te max range, we know this number is invalid.
    if (creditcardnumber > 5599999999999999)
    {
        printf("INVALID1\n");
        return 1;
    }
    else
    {

        //We copy the numbers in different ints, to use them later in different operations.
        float creditcardcopy = creditcardnumber;
        int creditcardcopy1 = creditcardnumber;
        //Start counting the digits, with a loop.
        int digitscount = 0;
        while (creditcardcopy > 1)
        {
            creditcardcopy = creditcardcopy/10;
            digitscount++;
        }

        //We know the length companies use, so if it is too short or too long, we
        //know the number is invalid.
        if ((digitscount!= 15) && (digitscount != 16) && (digitscount != 13))
        {
            printf("INVALID2\n");
            return 1;
        }
        else
        {
            //We initialize an array and with modulo we put each number in the right place.
            int number[digitscount];
            for (int i = digitscount; i > 0; i--)
            {
                number[i] = creditcardcopy1 % 10;
                creditcardcopy1 = creditcardcopy1 / 10;
            }

            //We made 2 arrays out of 1, so that we can leave 1 with the original
            //number and the other will have the second-to-last digits multiplied by 2.
            int counter = 1;
            while (counter < digitscount)
            {
                number[counter] = number[counter] * 2;
                counter = counter + 2;
            }

            //We need to sum the digits and not the products, so we subtract 10 from
            //all the numbers that are greater than 10 and count how many times we do tis
            //to represent the ones, that would be left.
            int tenscount = 0;
            int counter1 = 1;
            do
            {
                if(number[counter1] >= 10)
                {
                    number[counter1] = number[counter1] - 10;
                    tenscount++;
                    counter1 = counter1 + 2;
                }
                else
                {
                    counter1 = counter1 + 2;
                }
            }
            while (counter1 < digitscount);

            //We sum the multiplied digits + the tenscount.
            int sumdigitstotal = number[0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15] + tenscount;
            if (sumdigitstotal % 10 == 0)
            {
                if (digitscount == 15 && (number[0] == 3) && ((number[1] == 4)|| (number[2] == 7)))
                {
                    printf("AMEX\n");
                    return 0;
                }
                else
                {
                    if (digitscount == 16 && (number[0] == 5) && ((number[1] == 1)|| (number[2] == 2)|| (number[2] == 3)|| (number[2] == 4)|| (number[2] == 5)))
                    {
                        printf("MASTERCARD\n");
                        return 0;
                    }
                    else
                    {
                        if ((digitscount == 13 || digitscount == 16) && (number[0] == 4))
                        {
                            printf("VISA\n");
                            return 0;
                        }
                        else
                        {
                            printf("INVALID3\n");
                            return 1;
                        }

                    }
                }

            }
            else
            {
                printf("INVALID4\n");
                return 1;
            }

        }

    }
}
1
  • Why is creditcardcopy a float? float creditcardcopy = creditcardnumber;. I think it's better for you to leave the hacker sets for now and try to solve the normal ones. You don't have to solve them anyway. – ChrisG Aug 23 '15 at 14:17
2

1- converting longlong to int causes imprecision since int store 4bytes(32bits) and longlong store 8bytes(64bits) of intger values so you don't need int or float(for floating point numbers) which both are 4 byets you only need longlong because you know that credit card number will be greater than 4000,000,000 which is the maximum number can int or float hold and credit number will be in range of 10^13(10 multiplied by itself 13 time) and 10^16 so these are big numbers that int or float can't hold.

2- this line => if (creditcardnumber > 5599999999999999) what if the user provide this 1234567890 which is invalid credit card number in this case this condition will be false and accept this invalid number.

3- this line => int sumdigitstotal = number[0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15] + tenscount;

is totaly wrong because if you want to sum all elements stored in array you should't do this you should iterate on each element of the array and store values in variable something like this (sum = sum + number[i]). You can do this also with % and / only without using array for example int sum = 0; and when you do something for example as number = creditcardcopy1 % 10 then you can store the value in sum like this sum = sum + number at the end you will find all your values resulted from % and / stored in sum then you can check if sum % 10 == 0 or not but this condition => if (sumdigitstotal % 10 == 0) will always be false if it's total value % 10 doesn't equal 0 and this what is happen in your program

4- last thing you shouldn't return 1; at all because your program in all cases will print and exit with return 0; for example this line => printf("INVALID4\n"); this isn't error this is what program must print and exit correctly with return 0 when total value of credit card number % 10 not equal 0.

1

To be frank with you, your program has serious flaws that will not allow it to work in any case. But just to answer your question:

why it always prints INVALID4

It's because of this line

int sumdigitstotal = number[0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15] + tenscount;

because 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15 is equal to 110 so the above line is equal to

int sumdigitstotal = number[110] + tenscount;

Your program should not only not work correctly, but also give you a segfault because you are trying to access memory you haven't requested. Anyway, you probably wanted to write

int sumdigitstotal = number[0] + number[1] + number[2] + number[3] + number[4] + number[5] + number[6] + number[7] + number[8] + number[9] + number[10] + number[11] + number[12] + number[13] + number[14] + number[15] + tenscount;

Since number[110] will return garbage value, we can't be sure of the result, and then you add tenscount. That is probably never evenly divisible by 10, so if (sumdigitstotal % 10 == 0) is always false and so the else branch is always executed, giving you the INVALID4 message. But as I said before, and in the comment above, there are more problems with your code. Try to solve the normal ones first, and when you have the experience and the knowledge you will be able to solve the hacker ones too. Keep coding!

If this answers your question please accept it by clicking the gray check-mark to the left, so that it becomes green. You can also vote it up by pressing the up arrow above the check-mark.

You must log in to answer this question.

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