Switch statement using string on an array

前端 未结 8 1417
礼貌的吻别
礼貌的吻别 2021-01-13 06:28
#include

int main(){

    char name[20];

    printf(\"enter a name \");
    scanf(\"%s\",name);
    switch(name[20]){
        case \"kevin\" : 
             


        
8条回答
  •  北海茫月
    2021-01-13 07:24

    If you are after performing specific actions for specific strings this implies you know the strings in advance. This in turn implies their number is limited, is countable, like for example a set of N commands:

    const char * commands[] = {
     "command-1",
     "command-2",
     ...
     "command-N"
    

    }

    To address those commands inside the array above from your code using a swtich you need to know their index, which is error prone. So number them, give them an ID:

    enum Command_id {
      NO_COMMAND,
      COMMAND_1,
      COMMAND_2,
      //...
      COMMAND_N,
    };
    

    Now put the two above together using a struct:

    struct Command_info {
      const char * command;
      enum Command_id id;
    } command_infos[] = {
      {"", NO_COMMAND},
      {"command-1", COMMAND_1},
      {"command-2", COMMAND_2},
      // ...
      {"command-N", COMMAND_N},
    };
    

    Now you have nice mapping of strings and their related IDs. To be able to map from string to ID during runtime the mapping above needs to be searched. To do this in a efficient manner you want to us binary search. The C library proveids bsearch() for this. The only prerequsite is that the array to be searched need to sorted.

    To sort use qsort() also proveid by the C library. For qsort() to work we you need a comparsion function:

    int cmp_command_infos(const void * pvCI1, const void* pvCI2)
    {
      const struct Command_info * pCI1 = pvCI1;
      const struct Command_info * pCI2 = pvCI2;
    
      return strcmp(pCI1->command, pCI2->command);
    }
    

    Call qsort() like this

    qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
    

    Now as the array is sorted one can look it up using bsearch(). For "COMMAND-2" this would look like this:

        ... = bsearch(&(struct Command_info){"COMMAND-2", NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
    

    Putting all this together could result in:

    #include 
    #include 
    #include 
    
    
    enum Command_id {
      NO_COMMAND,
      COMMAND_1,
      COMMAND_2,
      //...
      COMMAND_N,
    };
    
    struct Command_info {
      const char * command;
      enum Command_id id;
    } command_infos[] = {
      {"", NO_COMMAND},
      {"command-1", COMMAND_1},
      {"command-2", COMMAND_2},
      // ...
      {"command-N", COMMAND_N},
    };
    
    
    int cmp_command_infos(const void * pvCI1, const void* pvCI2)
    {
      const struct Command_info * pCI1 = pvCI1;
      const struct Command_info * pCI2 = pvCI2;
    
      return strcmp(pCI1->command, pCI2->command);
    }
    
    
    int main(int argc, char ** argv)
    {
      qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
    
    
      {
        enum Command_id command_id = NO_COMMAND;
        struct Command_info * pCI = bsearch(&(struct Command_info){argv[1], NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
    
        if (NULL == pCI)
        {
          printf("Command = '%s' is unknown\n", argv[1]);
        }
        else
        {
          printf("Command = '%s' --> ID = %d\n", pCI->command, pCI->id);
    
    
          switch(command_id)
          {
            case COMMAND_1:
              /* perform action on COMMAND 1 here */
              break;
    
            case COMMAND_2:
              /* perform action on COMMAND 1 here */
              break;
    
            default:
              /* unknow command, do nothing */
              break;
          }
        }
      }
    }
    

    Call it like:

    ./a.out command-1
    

    giving:

    Command = 'command-1' --> ID = 1
    

    or:

    ./a.out command-bla
    

    giving:

    Command = 'command-bla' is unknown
    

    or even

    ./a.out ""
    

    giving:

    Command = '' --> ID = 0
    

提交回复
热议问题