-4

this is my implementation of LUHN algorithm In my code for the input i want to create an array of values whose length can vary according to the user input. below is what i tried but seems to be not working ...also if i need to use malloc function how can i use is it ? other than that everything works fine ,also suggest some optimizations that can be made.

#include<stdio.h>

int main()

{  char a[100];
   int sum=0,c=0,i;


     printf("enter the card you use\n");
     scanf("%16s",&a[i]);

     for(int m=0;a[m]!='\0';m++){

      c++;
     }

    for(int j=0;j<c;j++){
    int k,l;
    if(j%2==0){
    k=a[j]%10;
    l=a[j]/10;
    a[j]=k+l;   
    sum=sum + a[j];  
    }      
    else{
    sum = sum + 2*a[j];
    } 
    }                  
    if(sum % 10 ==0 && c==13)                   
    printf("VISA\n");
    else if(sum % 10==0 && c==16)
    printf("MASTERCARD\n");
    else if(sum % 10==0 && c==15)
    printf("AMERICAN EXPRESSWAY\n");
    else
    printf("INVALID\n");

    return 0;
}
user3315556
  • 175
  • 1
  • 8
  • 3
    Use pointers, search for malloc. – Andromeda Sep 04 '14 at 11:00
  • http://en.wikipedia.org/wiki/C_dynamic_memory_allocation – someuser Sep 04 '14 at 11:00
  • define array after user enter size of array or allocate array using malloc/calloc. – Jayesh Bhoi Sep 04 '14 at 11:03
  • @Jayesh yeah but if i don't want to enter the size initially rather let the user to enter as the characters ,is there a way to make array detect the size rather than entering manually? – user3315556 Sep 04 '14 at 11:11
  • Using `scanf("%d",&a[i]);` ensures that the person has to enter a space between each digit; if you use `%16s` instead (where 16 is the maximum card length you support), and read into a char buffer, then they don't have to do that. (You could then break the input string down into an int array). Also there is no real reason to use a variable size allocation here, just allocate enough for the longest possible card and ignore any input beyond that. – M.M Sep 04 '14 at 11:12
  • Your test logic is wrong too. If `c == 16` then `c != 13` is always true (because `16 != 13`). `||` has lower priority than `&&`, so the first test says that any 13-digit card is VISA even if it failed checksum. But even if you fix that then the MASTERCARD case never can trigger. (Actually you need to inspect the actual digits to decide between Visa and Mastercard, they can both be 16-digit and with correct checksum - but there is a standardized assignment of number ranges to each acquirer). – M.M Sep 04 '14 at 11:15
  • @MattMcNabb ok so if i fix the maximum length of array say 16 , the user has to enter 16 digits even is his card number length is 13 ? – user3315556 Sep 04 '14 at 11:28
  • No, you have the user enter some digits and then press Enter when he is done. (This has to happen anyway,even with your approach) – M.M Sep 04 '14 at 11:30
  • @MattMcNabb when i run the code i enter 15 values and press enter it keeps on asking for more values? – user3315556 Sep 04 '14 at 11:35
  • @user3315556 do it once, not 16 times, and read into a char array. You cannot read into an int array using `%s`. You need to make a few other changes too, I am just giving you a general idea of a better approach. – M.M Sep 04 '14 at 11:37
  • @MattMcNabb any more bug? – user3315556 Sep 04 '14 at 11:58

2 Answers2

2

There are several things wrong with your code.

For one: you didn't initialise a, but have a for loop condition on it straight away for(int i=0;a[i]!='\0';i++).

To your question:

If you know at runtime the length of the required array, then you can allocate heap memory for it with

void * array_ptr = malloc(size_of_array_element * num_elements);

Or on the stack (C99 and above):

type array[num_elements];

If the size of your array changes throughout runtime then you have to allocate it using malloc (or calloc) and resize it as nessessary:

void * resized_array_ptr = realloc(array_ptr, size_of_array_element * num_elements);
Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • You can alloc on stack with C90 using alloca() library function. – Eldar Dordzhiev Sep 04 '14 at 11:07
  • @EldarDordzhiev `alloca` is an option, but I would discourage it's use. It is also not widely supported by all compilers and has dangers associated with inlining within loops. C99 VLAs are far more stable and achieve the same result. – Sergey L. Sep 04 '14 at 11:09
  • is there a way to make array resize itself accordingly when the user enters the character rather than manually entering the size of array? – user3315556 Sep 04 '14 at 11:14
  • I know, but some people can assume, that there's no way to alloc on stack until C99 :) – Eldar Dordzhiev Sep 04 '14 at 11:14
  • @user3315556 try this http://stackoverflow.com/questions/8164000/how-to-dynamically-allocate-memory-space-for-a-string-and-get-that-string-from-u I think there's a library function for that, but I can't recall its name – Eldar Dordzhiev Sep 04 '14 at 11:16
  • @user3315556 in C it is not possible to have auto-resizing arrays. This is C for you. You have all the power, but also all the responsibility. In C++ something like that could be done. – Sergey L. Sep 04 '14 at 11:17
1

i want to create an array of values whose length can vary according to the user input.

You can defined your array after the user input like

int userinput;
scanf("%d\n",&userinput);
int arr[userinput];

Using malloc you can do by

int *arr= malloc(sizeof(int)*userinput);
Jayesh Bhoi
  • 24,694
  • 15
  • 58
  • 73