lookup table in c

前端 未结 4 2059
误落风尘
误落风尘 2021-01-03 00:58

I\'m creating a lookup table in C When I define this:

typedef struct {
 char* action;
 char* message;
} lookuptab;

lookuptab tab[] = {
  {\"aa\",\"bb\"},
           


        
4条回答
  •  说谎
    说谎 (楼主)
    2021-01-03 01:37

    You need to specify a size for the message array member in the struct definition:

    #define N ... // maximum number of elements in message array
    
    typedef struct
    {
      char *action;
      char *message[N]; 
    } lookuptab;
    
    lookuptab tab[] = {
      {"aa", {"bb", "cc"}},
      {"dd", {"ee", "ff"}},
      ...
    };
    

    In this case, N must be at least 2.

    If you want each instance of the lookuptab struct to have a different number of elements in the message array, then you will have to allocate each message array separately, meaning you won't be able to use a static initializer:

    typedef struct
    {
      char *action;
      char **messages;
    } lookuptab;
    
    lookuptab *newEntry(const char *action, size_t numMessages, ...)
    {
      lookuptab *entry = malloc(sizeof *entry);
      if (entry)
      {
        entry->action = malloc(strlen(action) + 1);
        if (entry->action)
          strcpy(entry->action, action);
        if (numMessages > 0)
        {
          entry->messages = malloc(sizeof *entry->messages * numMessages);
          if (entry->messages)
          {
            size_t i;
            va_list ap;
    
            va_start(ap, numMessages);
    
            for (i = 0; i < numMessages; i++)
            {
              char *nextMessage = va_arg(ap, char *);
              entry->messages[i] = malloc(strlen(nextMessage) + 1);
              if (entry->messages[i])
                strcpy(entry->messages[i], nextMessage);
            }
          }
        }
      }
      return entry;
    }
    
    int main(void)
    {
      lookuptab *tab[ENTRIES]; // for some number of ENTRIES
      tab[0] = newEntry("AA", 2, "BB", "CC");
      tab[1] = newEntry("DD", 3, "EE", "FF", "GG");
      tab[2] = newEntry("HH", 0);
      ...
    }
    

    Instead of passing the number of messages explicitly, you can use a sentinel:

      tab[0] = newEntry("AA", "BB", "CC", NULL);
    

    but you'll either have to cycle through all the arguments twice (first to get the number to allocate the messages array, then to copy each message) or you'll have to realloc() your array for each message, such as:

    size_t numMessages = 0;
    ...
    char *nextMessage
    while ((nextMessage = va_arg(ap, char *)) != NULL)
    {
      char **tmp = realloc(entry->messages, sizeof *entry->messages, numMessages+1);
      if (tmp)
      {
        entry->messages = tmp;
        entry->messages[numMessages] = malloc(strlen(nextMessage) + 1);
        strcpy(entry->messages[numMessages], nextMessage);
        numMessages++;
      }
    }
    

提交回复
热议问题