Dvole Dvole - 3 months ago 8
C Question

C Array behaves different with different number of digits, why?

I have a code that gets a number from input and then puts it into array, and then prints said array. But there is very strange side-effect, when I enter 13 digit number, my last digit is wrong. If I enter 15 or 16 digit number everything is fine. I can't understand what's happening! Here is the code:
numberDigits is either 12, 14 or 15, based on the number of digits in number.

int myNumber[numberDigits];
for (int i = 0; i <= numberDigits; i++)
{
myNumber[numberDigits - i] = number % 10;
number = number / 10;
}
printf("\n");

for (int i = 0; i <= numberDigits; i++)

{
printf("%i",myNumber[i]);
}


EDIT:
My number is initialized as long long int. Here is a check to verify number of digits:

if (number / 1000000000000 >= 1 && number / 1000000000000 < 10)
{
numberDigits = 12;
}
if (number / 100000000000000 >= 1 && number / 100000000000000 < 10)
{
numberDigits = 14;
}
if (number / 1000000000000000 >= 1 && number / 1000000000000000 < 10)
{
numberDigits = 15;
}


EDIT: Last update, Yes, I have updated my code and it works as expected with your suggestions, but I need to understand why my code doesn't work. I think that maybe array[12] actually holds 12 elements and not 13, and when I access element array[12] with it, I get some random value from memory, but why this doesn't happen with array[14] or array[15] with 15 and 16 digit numbers respectively. And why program does not crash as it should when you access array at wrong position. Original question below with old code that doesn't work.

EDIT: Here is whole listing for those interested.

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

int verify (long long int number);

int main(void)

{
printf("Please enter card number: \n");
long long int number = GetLongLong();
// AMEX uses 15 digits
if (number > 100000000000000 && ((number / 10000000000000 == 34) || (number / 10000000000000 == 37)))
{

printf("AMEX");

}

if (number > 1000000000000 && number < 10000000000000 && (number / 1000000000000 == 4))
{
printf("VISA");
}

if (number > 1000000000000000 && number < 9999999999999999 && (number / 1000000000000000 == 4))
{
printf("VISA");
}

if (number > 1000000000000000 && number < 9999999999999999 && (number / 100000000000000 == 51 || number / 100000000000000 == 52 || number / 100000000000000 == 53 || number / 100000000000000 == 54 || number / 100000000000000 == 55))
{
printf("MASTERCARD");
}

return verify(number);
}



int verify (long long int number)
{
int numberDigits;
if (number / 1000000000000 >= 1 && number / 1000000000000 < 10)
{
numberDigits = 12;
}
if (number / 100000000000000 >= 1 && number / 100000000000000 < 10)
{
numberDigits = 14;
}
if (number / 1000000000000000 >= 1 && number / 1000000000000000 < 10)
{
numberDigits = 15;
}

int myNumber[numberDigits];
for (int i = 0; i <= numberDigits; i++)
{
myNumber[numberDigits - i] = number % 10;
number = number / 10;
}
printf("\n");

for (int i = 0; i <= numberDigits; i++)

{
printf("%i",myNumber[i]);
}

return 0;
}

Answer

I think it should be something like this:

for(int i = 0; i < numberDigits; ++i) printf("%d",myNumber[i]);

instead of:

for(int i = 0; i <= numberDigits; ++i) printf("%i",myNumber[i]);

And in the first loop:

myNumber[numberDigits - (i + 1)] = number % 10;

Also, you could use something like this to know the number of digits:

int digits(long long num) {
  if(!num) return 1;
  return log10(num) + 1;
}