Home > Net >  Transform if statement into switch case
Transform if statement into switch case

Time:10-29

I have the problem that I can't manage to convert this if statment into a switch case function. The function gets a value either SEND,LIST,READ,DEL,Quit and after that something else should happen with it.

int getCommand(char *buffer){

int action = 0;


if((buffer[0] == 's' && buffer[1] == 'e' && buffer[2] == 'n' && buffer[3] == 'd')
|| (buffer[0] == 'S' && buffer[1] == 'E' && buffer[2] == 'N' && buffer[3] == 'D')){
    action = 1;
}
else if((buffer[0] == 'l' && buffer[1] == 'i' && buffer[2] == 's' && buffer[3] == 't')
|| (buffer[0] == 'L' && buffer[1] == 'I' && buffer[2] == 'S' && buffer[3] == 'T')){
    action = 2;
}
else if((buffer[0] == 'r' && buffer[1] == 'e' && buffer[2] == 'a' && buffer[3] == 'd')
    || (buffer[0] == 'R' && buffer[1] == 'E' && buffer[2] == 'A' && buffer[3] == 'D')){
    action = 3;
}
else if((buffer[0] == 'd' && buffer[1] == 'e' && buffer[2] == 'l')
    || (buffer[0] == 'D' && buffer[1] == 'E' && buffer[2] == 'L')){
    action = 4;
}
else if((buffer[0] == 'q' && buffer[1] == 'u' && buffer[2] == 'i' && buffer[3] == 't')
    || (buffer[0] == 'Q' && buffer[1] == 'U' && buffer[2] == 'I' && buffer[3] == 'T')){
    action = 5;
}

return action; }

Is there maybe also a way to write this better?

Is there maybe also a way to write this better?

CodePudding user response:

You could possibly do a switch statement if all the strings "send", "list" etc were of the same length, by treating the string data as an integer.

But, since you have two different lengths of 3 and 4 you would need two switch statements which is not so nice. I would instead suggest something like below.

if (!strncmp(buffer, "send", 4) || !strncmp(buffer, "SEND", 4))
    action = 1;
else if (!strncmp(buffer, "list", 4) || !strncmp(buffer, "LIST", 4))
    action = 2;
else if (!strncmp(buffer, "read", 4) || !strncmp(buffer, "READ", 4))
    action = 3;
else if (!strncmp(buffer, "del", 3) || !strncmp(buffer, "DEL", 3))
    action = 4;
else if (!strncmp(buffer, "quit", 4) || !strncmp(buffer, "QUIT", 4))
    action = 5;

Please note there is also strnicmp, which is case insensitive and would match e.g "SeNd", this would eliminate the need for separate recognition of upper/lower case.

CodePudding user response:

You could do something like:

#include <string.h>
#include <stdio.h>

char *actions[] = { "SEND", "LIST","READ", "DEL", "Quit" };

int
main(int argc, char **argv)
{
    (void)argc;
    for( argv  = 1; *argv; argv  = 1 ){
        int action = -1;
        for( int i = 0; i < sizeof actions / sizeof *actions; i  = 1 ){
            if( strcasecmp(*argv, actions[i]) == 0 ){
                action = i;
                break;
            }
        }
        printf("for %s, action = %d\n", *argv, action);
    }

    return 0;
}

Note that this maps SEND to zero, so add 1 if you want to be consistent with the actions you have in your original code, or shift the array, or ...

CodePudding user response:

If buffer contain string (null-terminated array of characters) and comparison can be truly case-insensitive, you can declare array of action names and search in it with strcasecmp():

    int action = 0;

    const struct {
        const char *name;
        int action;
    } actions[] = {
        { "send", 1 },
        { "list", 2 },
        { "read", 3 },
        { "del",  4 },
        { "quit", 5 }
    };

    for (unsigned i = 0; i < sizeof(actions)/sizeof(*actions);   i)
    {
        if (strcasecmp(buffer, actions[i].name) == 0)
        {
            action = actions[i].action;
            break;
        }
    }

Note "send" will match not only "send" and "SEND" but also "Send", "seND" etc.

CodePudding user response:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* public domain code use at your own wish (only toUpper function) */
char* toUpper(char* s) {
    char* str = malloc(strlen(s) 1);
    strcpy(str, s);
    for(unsigned int i = 0; i < strlen(s);   i)
        str[i] -= 32 * ((str[i] >= 97) && (str[i] <= 122));
    return str;
}
unsigned getCommand(char* str) {
    char* s = toUpper(str);
    unsigned action = 0;
    action  = 1 * (!strcmp(s, "SEND"));
    action  = 2 * (!strcmp(s, "LIST"));    
    action  = 3 * (!strcmp(s, "READ"));    
    action  = 4 * (!strcmp(s, "DEL"));    
    action  = 5 * (!strcmp(s, "QUIT"));    
    free(s);
    return action;
}

Another version, mostly branchless solution (except for strcmp which does internally). Not every libc has strnicmp because it is not standard.

  • Related