Array initialization from text string I have a block of text where several arrays are printed out, with a name and values:

VAL1=10 20 30 40 50
VAL2=4 8 15 16 23 42

I have a function that looks for the value name, and sets an array of these values:
bool FetchValueArray(char* source, char* name, char* typeFormat, int count, void* destination, size_t destElementSize)
{
    int i;
    char *t;
    t=strstr(source,name);
    if (t)
        if (destination != NULL)
        {
            for (i = 0;i &lt; count;i++)
                sscanf(t, typeFormat, (char*)destination + destElementSize * i);
            return true;
        }
    return false;
}

Called thus:
FetchValueArray(source, &quot;VAL1=&quot;, &quot;%d&quot;, 5, val1array, sizeof(val1array[0]);
FetchValueArray(source, &quot;VAL2=&quot;, &quot;%d&quot;, 6, val1array, sizeof(val1array[0]);

This is from a StackOverflow question. As the answerer wrote, it works, but it's not safe. If I call it with a count that is higher than the size of the array, I will corrupt the memory. I'm trying to wrap my head around this one and having a tough time. How can I have a function that will set values to a fixed array and be &quot;safe&quot;?
I'm not quite sure what you are asking for, but I guess you are looking for a solution similar to this (not compiled nor tested):

#include &lt;stdio.h&gt;   /* sscanf */
#include &lt;stddef.h&gt;  /* NULL */
#include &lt;stdbool.h&gt; /* C99 bool type */

typedef enum
{
  TYPE_CHAR  = 'c',
  TYPE_INT   = 'd',
  TYPE_FLOAT = 'f',
  // etc
} Type_t;



/* I placed destination first to use the same parameter order as standard library
   functions (strstr for example). Note the const correctness for read-only parameters. */

bool FetchValueArray (void*       dest, 
                      const char* source,
                      const char* name,
                      size_t      count,
                      Type_t      type)

{
  const char* strptr;                  /* Some string pointer (not sure what it does) */
  BOOL is_found;                       /* Is the name found? */

  if(dest == NULL)                     /* No need to do anything if this parameter is NULL */
  {
    return false;
  }


  strptr = strstr(source, name);
  is_found = strptr != NULL;           /* Boolean arithmetic */

  if(is_found)
  {
    size_t i;
    size_t item_size;
    const char format[2] = {'%', (char)type};

    switch(type)
    {
      case TYPE_CHAR:  item_size = 1; break;
      case TYPE_INT:   item_size = 4; break;
      case TYPE_FLOAT: item_size = 4; break;
    }

    for(i=0; i&lt;count; i++)
    {
      sscanf(strptr, format, (char*)dest + item_size*i);
    }
  }

  return is_found;
}


EDIT:
Regarding array bounds checking. First you have to decide whether this is actually your concern or if you should leave it up the caller. Most commonly, you document every parameter in the .h file and state how the function should be called. If someone still decides to call it with incorrect parameters, it is then their own fault. That's how most C functions work and in this particular case, that's what I would recommend. 

Since C does not store the array size together with the array as one single data type, you can't really pass an array size "safely" between the caller and a function, the caller is the one with the knowledge about the size, so you simply have to trust the programmer writing the caller.

You could write something like this

bool FetchValueArray(char dest[25], ...


but there are still no guarantees by the standard that this is safe. Some compilers will toss a warning if you try to pass anything but a fixed char array of 25 items to this function, but they don't have to. And we'd lose the generic type, so it isn't helpful.

You could do something like this, but I would not recommend it:

#define SIZE 25

typedef union
{
  char  char_array[SIZE];
  int   int_array[SIZE];
  float float_array[SIZE];

} GenericSafeArray_t;


This will allocate SIZE*sizeof(float), since float happend to be the largest type. So it is memory-ineffective and not particularly flexible either.