Is it possible to rewrite following so I only have to change in one place if the string changes?
#define MY_STRING "Foo bar"
#define MY_STRING_FIRST_CHAR 'F'
The following is not acceptable since it refers to a char in a memory location, so it can't be used as a case in a switch
statement:
#define MY_STRING_FIRST_CHAR MY_STRING[0]
switch (something) {
case MY_STRING_FIRST_CHAR:
break;
}
The purpose is to efficiently parse a received string by looking at one character. In my case all strings have one unique character. The following is not my actual code, but a very simple example to show the principle:
#define COMMAND_LIST "list"
#define COMMAND_LIST_FIRST_CHAR 'l'
#define COMMAND_CHANGE "change"
#define COMMAND_CHANGE_FIRST_CHAR 'c'
#define COMMAND_EXIT "exit"
#define COMMAND_EXIT_FIRST_CHAR 'e'
switch(received_command_string[0]){
case COMMAND_LIST_FIRST_CHAR:
// Do the "list" stuff
break;
case COMMAND_CHANGE_FIRST_CHAR:
// Do the "change" stuff
break;
case COMMAND_EXIT_FIRST_CHAR:
// Do the "exit" stuff
break;
}
User "pmg" found this in the gcc documentation: "There is no way to convert a macro argument into a character constant."
I wanted the definitions to be in an include file that can be shared by several source files. This is as close as I can get while only have every character defined in one place:
#include <stdio.h>
#define CH0 'F'
#define CH1 'o'
#define CH2 'o'
#define CH3 ' '
#define CH4 'b'
#define CH5 'a'
#define CH6 'r'
static char MY_STRING[] = { CH0, CH1, CH2, CH3, CH4, CH5, CH6, '\0'};
#define MY_STRING_FIRST_CHAR CH0
void main(void){
printf("The string is %s, the first char is %c\n", MY_STRING, MY_STRING_FIRST_CHAR);
}
I will not do it that way. The original question was if it is possible to share one definition to get both a string constant and a character constant. By wasting clock cycles at run-time there are several solutions to my problem.
You can do that with writing each symbol once ... but on different definitions
#include <stdio.h>
#define COMMAND_LIST_FIRST_CHAR 'l'
#define COMMAND_LIST (char[]){ COMMAND_LIST_FIRST_CHAR, 'i', 's', 't', 0 }
int main(void) {
char received_command_string[] = "list";
switch (received_command_string[0]) {
case COMMAND_LIST_FIRST_CHAR:
printf("Doing the \"list\" stuff for '%s'\n", COMMAND_LIST);
break;
default:
break;
}
return 0;
}
Why do you absolutely want to use a switch case?
Instead you could use a mapping table that match your string and the handling function. Then you simply have to iterate over the table.
typedef struct {
char * key;
void (func*)(void);
} MAP_ENTRY;
MAP_ENTRY map [] = {
{"list", listHandler},
{"change", changeHandler},
{"exit", exitHandler},
};
for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) {
if (map[i].key[0] == received_command_string[0]) {
map[i].func();
break;
}
}
Then you just have to move the processing code from your switch/case into the corresponding handler function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With