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.