If you don't know and have not even an upper limit to the numbers of commas in the string, you have to parse the string and dynamically reallocate the array. There are several strategies, and the one below isn't really optimal, being conducive to memory fragmentation, but it's simple to describe.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *str = "This,is,a,comma,delimited,string,with,a,length,of,whatever";
char **array = NULL;
char *p;
size_t items = 0, q;
char *sepa = ",";
p = str;
for (;;)
{
p += strspn(p, sepa);
if (!(q = strcspn(p, sepa)))
break;
if (q)
{
array = realloc(array, (items+1) * sizeof(char *));
array[items] = malloc(q+1);
strncpy(array[items], p, q);
array[items][q] = 0;
items++;
p += q;
}
}
for (q = 0; q < items; q++)
{
printf("(%s) ", array[q]);
}
printf("\n");
/* Here we have a problem. How do we return to the caller the information
about how many items do we have? A common solution is to return the number
of items PLUS ONE, and that one is NULL */
array = realloc(array, (items+1) * sizeof(char *));
array[items] = NULL;
/* So this code can work without needing to know the value of "items" */
for (q = 0; array[q]; q++)
printf("(%s) ", array[q]);
printf("\n");
}
BTW, I have omitted to check whether realloc (or malloc) returns NULL, signifying a memory error.
An alternative allocation strategy is to use realloc in chunks, i.e., you keep two counters, items and really_allocated_items, and only realloc when the two are equal. When you do, you increment really_allocated_items by, say, 64, and realloc that number of items. This way, you only run one allocation every 64, and waste at most 63 pointers.
Other strategies exist, using an incrementing chunk size instead of the fixed 64, but they are only implemented when memory and performance constraints are really tight.
NOTE this implementation intentionally does not use strtok, because strtok modifies the original string and in some cases this might not be allowed (might even gain you a coredump).