0

If I were to compare these enum values in a switch statement. What is the purpose of numbering the strings?

If I store the enum in a header file and then import the header file. I know that I can say events event = ls; (I can store ls into events)

But can I say something like event[0] to access ls?

#define NUM_EVENTS 11
typedef enum events {
    ls = 0,
    rs = 1,
    ws = 2,
    lo = 3,
    ro = 4,
    lc = 5,
    rc = 6,
    gru = 7,
    grl = 8,
    gll = 9,
    glu = 10
} events;
2
  • How exactly do you plan to use it? There may be a different solution you are missing if given a little more context. Commented Oct 12, 2017 at 22:46
  • typedef enum events { ls, rs, ws, lo, ro, lc, rc, gru, grl, gll, glu } events; does the exact same thing. enum always begins numbering at zero. You only need explicit initialization if you are doing something different, e.g. enum { ls = 10, rs, ws, lo, ro, lc, rc, gru = 20, ... } would result in 10, 11, 12, 13, 14, 15, 16, 20, 21, 22, 23. Commented Oct 13, 2017 at 5:27

4 Answers 4

1

There's no such thing as enum strings. What you're talking about are identifiers, only used in the source code. An enum in C is represented as an integer type, typically int, but compilers are free to chose e.g. short or another one. An enum is even allowed to hold a value that doesn't correspond to one of the named members. Only these numbers go in the compiled programs. C compilers do not (have to) store any type information in the compiled executable.

So, if you need the enum identifiers as strings at runtime, you have to store them yourself. This typically looks like e.g.

typedef enum events {
    ls,
    rs,
    ws,
    lo,
    ro,
    lc,
    rc,
    gru,
    grl,
    gll,
    glu
} events;

static const char *event_names[] = {
    "ls",
    "rs",
    "ws",
    "lo",
    "ro",
    "lc",
    "rc",
    "gru",
    "grl",
    "gll",
    "glu"
};

void example(event ev)
{
    // might want to check for a valid value here ...

    // print name of event
    puts(event_names[ev]);
}

As a side note, there's no need to explicitly number the members in your case -- the default numbering starts at 0 and increases by one for each member.


Further hints:

  • enum member identifiers are global, so it's a good practice to make them unique, e.g. by prepending the type name like this:

    typedef enum events {
        event_ls,
        event_rs,
        // ...
    } events;
    
  • The above code violates the DRY (don't repeat yourself) principle: when changing the enum, you have to touch two different locations in the code which is a source of potential bugs. This is sometimes solved using X macros. There are opposing opinions whether this is good or bad style, just presenting it here for completeness:

    #define EVENTS_LIST \
        X(ls) \
        X(rs) \
        X(ws) \
        X(lo) \
        X(ro) \
        X(lc) \
        X(rc) \
        X(gru) \
        X(grl) \
        X(gll) \
        X(glu)
    
    #define X(name) event_##name ,
    typedef enum events {
        EVENTS_LIST
    } events;
    #undef X
    
    #define X(name) #name ,
    static const char *event_names[] = {
        EVENTS_LIST
    };
    #undef X
    

    after preprocessing, this produces

    typedef enum events {
        event_ls , event_rs , event_ws , event_lo , event_ro , event_lc , event_rc , event_gru , event_grl , event_gll , event_glu ,
    } events;
    
    static const char *event_names[] = {
        "ls" , "rs" , "ws" , "lo" , "ro" , "lc" , "rc" , "gru" , "grl" , "gll" , "glu" ,
    };
    
Sign up to request clarification or add additional context in comments.

Comments

0

You can cast from an integer to an enum, which is equivalent to indexing if the enum is a dense sequence starting at zero. In general enums are just a way to introduce symbolic names for a list of related constants. It is syntactically better than doing so using #define but there is very little functionality beyond such. If the numbers are not explicitly assigned, the compiler will manage assigning unique values to each member. But even finding the max value is not something offered by the language, much less mapping to names as strings or similar.

Comments

0

I think you are asking how to get the name of the event as a string from the event so you can do something like printf("%s\n", SOMEFUNCTION(event)); to print the name of the event.

There's is no such function.

1 Comment

We are all just sitting here guessing at what his question was lol
0

If you really want to use event[0] you can do this:

events event[11];
event[0] = ls;
event[1] = rs;
event[2] = ws;
event[3] = lo;
event[4] = ro;
event[5] = lc;
event[6] = rc;
event[7] = gru;
event[8] = grl;
event[9] = gll;
event[10] = glu;

I will say though, I am sure there is a way around doing this ( since it is not elegant at all ), if you give more context :)

EDIT: After re-reading your question, I get the impression you want the STRING "ls" from your enum?

If this is so, then no you are not able to do this. Enumerated types are great for switch statements, but if you are trying to turn a variable name into a string through code without hardcoding event[0] = "ls", it isn't going to happen.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.