title: Generic enum to text lookup in C
body: <p>[Update]</p>
  
  <ol>
  <li>the code given does actually work. I was mistaken when I thought that it did not. My bad; sorry++. If you can improve the code, please do so at <a href="https://codereview.stackexchange.com/questions/150480/generic-enum-to-text-lookup-in-c">https://codereview.stackexchange.com/questions/150480/generic-enum-to-text-lookup-in-c</a></li>
  <li>We <strong><em>must</em></strong> declare our strings at compile time. We code embedded systems and are not allowed to <code>malloc()</code>. Sorry for not being so clear.</li>
  </ol>
  
  <hr>
  
  <p>[Update++] I will probably accept one of the answers below. I forgot to state, though, that our enums are non-contiguous and have a wide range, which can make a difference</p>
  
  <hr>
  
  <p>The intertubes, and this site, are awash with questions asking for to get text from an enum.</p>
  
  <p>I cannot find a canonical way to do this (and would accept one as answer to this question), so let's see if we can cobble one together between us.</p>
  
  <p>Throughout our code, we have multiple arrays of structures, containing pairs of enums and corresponding strings. </p>
  
  <p>The problem is that the strings have different lengths, so we code a lookup function for each one, which for loops over an array of structures, trying to match the enum and returning the corresponding text if a match is found.</p>
  
  <p>Let’s take the following two contrived examples:</p>
  
  <pre><code>// +=+=+=+=+=+=+=+=+=+=+=+=+=+=
  typedef enum
  {
      north,
      south,
      east,
      west
  } E_directions;
  
  struct direction_datum
  {
      E_directions direction;
      char         direction_name[6];
  };
  
  struct direction_datum direction_data[] =
  {
      {north, "north"},
      {south, "south"},
      {east,  "east"},
      {west,  "west"},
  };
  
  // +=+=+=+=+=+=+=+=+=+=+=+=+=+=
  typedef enum
  {
      hearts,
      spades,
      diamonds,
      clubs,
  } E_suits;
  
  struct suit_datum
  {
      E_suits suit;
      char    suit_name[9];
  };
  
  struct suit_datum suit_data[] =
  {
      {hearts,   "hearts"},
      {spades,   "spades"},
      {diamonds, "diamonds",},
      {clubs,    "clubs"},
  };
  </code></pre>
  
  <p>Apart from the string length, they are similar/identical, so, in theory, we should be able to code a generic function to loop over either <code>direction_data</code> or <code>suit_data</code>, given an index and return the corresponding text. </p>
  
  <p>I am thinking something like this – but it doesn’t work (the enum value in the struct always seems to be zer0, so obviously my pointer arithmetic is off).</p>
  
  <p>What am I doing wrongly?</p>
  
  <pre><code>char *Get_text_from_enum(int enum_value, 
                           void *array, 
                           unsigned int array_length, 
                           unsigned int size_of_array_entry)
  {
      unsigned int i;
      unsigned int offset;
  
      for (i = 0; i &lt; array_length; i++)
      {
          offset = i * size_of_array_entry;
  
          if ((int) * ((int *) (array+ offset)) == enum_value)
              return (char *)  (array + offset + sizeof(int));
      }
  
      return NULL;
  }
  
  
  printf("Expect south,    got %s\n", 
            Get_text_from_enum(south,    
                               direction_data, 
                               ARRAY_LENGTH(direction_data),  
                               sizeof(direction_data[0])));
  
  printf("Expect diamonds, got %s\n", 
            Get_text_from_enum(diamonds, 
                               suit_data,      
                               ARRAY_LENGTH(suit_data),       
                               sizeof(suit_data[0])));
  </code></pre>