sherrellbc
sherrellbc

Reputation: 4853

How to implement an enum with specific values for its members?

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

Answers (5)

Marian
Marian

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

perreal
perreal

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

SamMan
SamMan

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

Sorcrer
Sorcrer

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

unwind
unwind

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

Related Questions