Reputation: 4853
I could be going about this all wrong, and it could be that an enum does is not a good way to solve this problem, but I am really not sure where to go with it otherwise.
Basically, I have non-sequential codes that correspond to certain strings. For example,
9 = "Enter"
10 = "Right"
15 = "Left"
17 = "Down"
And so on. I currently have this implemented with a large set of definitions:
#define ENTER_INDEX 0
#define RIGHT_INDEX 1
That is used to index into a char* array:
char* array[] = { "Enter", "Right" };
And when I receive information regarding which code was received, I then print the strings with a huge switch
-case.
Any ideas on how to do this more efficiently? Is an enum
a good approach?
Upvotes: 0
Views: 72
Reputation: 7472
A huge switch is not a bad solution. The question is why do you need an extra array of names. Why don't you return directly string literals from the switch?
char *name(int code) {
switch (code) {
case 9: return("Enter");
case 10: return("Right");
case 15: return("Left");
...
}
}
Upvotes: 1
Reputation: 97948
You can also create a map during initialization:
#include<stdio.h>
typedef struct { int code; const char *str; } key_info;
key_info keys[] = {
{9, "Enter"}, {10, "Right"}, {15, "Left"}, {-1, NULL}
};
#define MAX_KEY_CODE 15
size_t keymap[MAX_KEY_CODE + 1];
int main ( ) {
size_t i;
for (i = 0; keys[i].str; i++) {
keymap[keys[i].code] = i;
}
printf("%s\n", keys[keymap[10]].str);
return 0;
}
Upvotes: 1
Reputation: 98
A dictionary or hash table can be used. In c++ stl libraries I don't recall the name of the collection but in short y. use dictionaries/hashtables with generics.
So in your case you fill up the dictionary with key value pairs and when your later use the collection you can get a value using your key.
So it gets rid of switch statements and enums and will allow you to map any two types. Here is pseudo code
Value = dictionary[key]
So if key is 0 then the value will be set to Enter based on your example.
In short lookup examples for c++ and dictionary as I am answering from mobile phone and could not direct you to the exact collection name.
Upvotes: 1
Reputation: 1644
To implement an enum with specific values for its members can be done by
enum options_en
{
Enter=9,
Right=10,
Left=15,
Down=17,
Default=0;
} ;
then you can declare a variable which can take only values defined in the enumerated type
options_en opt_val = Default;
For exploring more information about your question , refer this link, Found it very useful and is relevent to your question
http://www.cprogramming.com/tutorial/enum.html
Upvotes: 1
Reputation: 399803
Sure, you can use an enum
, but that won't help you associate the names with the numerical values.
The problem is that you can't declare an enum and a string "in parallel" from the same source code characters, without using trickery such as X macros. Even then you probably won't solve the requirement for different casing which your code shows. Which you might want to avoid, because obfuscation.
The enum
would be just:
typedef enum {
ID_ENTER = 9,
ID_RIGHT = 10,
ID_LEFT = 15,
ID_DOWN = 17
} Id;
I would then use C99's fantastic support for explicit indexes in array initializers to declare an array of strings indexed by an Id
:
static const char *id_names[] = {
[ID_ENTER] = "Enter",
[ID_RIGHT] = "Right",
/* add more */
};
Note that the above is independent of the order, since each element initializer has an explicit index. This makes it very robust.
You can of course use a macro to cut down on the repetition, but that will make an all-caps string array:
#define DECL_ID(i) [ID_ ## i] = #i
static const char *id_names2[] = {
DECL_ID(ENTER), DECL_ID(RIGHT), /* add more */
};
Upvotes: 3