1

So I have the following enum and I have some states in each of which I want to print the STATUS instance based on event_id. So is there a way to compute the enum "string" from its value?

typedef enum {
   WIFI_START,
   WIFI_DIS,
   WIFI_CON
} STATUS;

void eventHandler(int event_id) 
{

  if (event_id == WIFI_START) {
     // ...
     printf ("WIFI_START is triggered");
  }
  ...
}
MKD
  • 53
  • 1
  • 6
  • 5
    Why not use a string array that maps to the enum indexes, i.e. `char *status[] = {"WIFI_START", ...}`? – ggorlen Sep 02 '20 at 00:29
  • 1
    You could with a little macro magic. – tadman Sep 02 '20 at 00:34
  • so am I iterating over the entire array to determine which event really occurred based on the `event_id`? @ggorlen – MKD Sep 02 '20 at 00:34
  • 1
    No, once you have the array above just write `printf("%s is triggered\n", status[event_id]);`, right? `WIFI_START == 0` and so forth. – ggorlen Sep 02 '20 at 00:35
  • gotcha. just looked a bit into the code and looks like `STATUS` is a part of the vendor library that I'm using which I can't modify. – MKD Sep 02 '20 at 00:37
  • Reflection is what you are looking for here, but C doesn't support it. @ggorlen's answer is probably the best, – Michael Dorgan Sep 02 '20 at 00:46
  • 1
    Remember that enumerations are nothing more than a way to introduce named symbolic integer constants. Unless explicitly change (which the enumeration in the question doesn't do) the first will always have the value `0`, and the rest will always be one larger than the previous. That's why the can be used as array indexes directly. And you can define and initialize such an array of names in your own code, independent of the library defining the enumeration. – Some programmer dude Sep 02 '20 at 00:47
  • Remember, the string array suggested by @ggorlen doesn't need to be in the library containing it. You can still declare the string array right where you wan to print it. Another option would be to just printf("%d", event_id); and do the lookup yourself. – Durstann Sep 02 '20 at 00:58
  • [macro magic](https://stackoverflow.com/questions/6635851/real-world-use-of-x-macros/6636596#6636596) – luser droog Sep 02 '20 at 01:29
  • @Someprogrammerdude Wouldn't defining an array containing the strings that are "used in enums" in my application itself be duplication...sort of? – MKD Sep 02 '20 at 02:44
  • @Durstann I understand, but the library has something which isn't directly being used and instead you're trying to create something different that relates to it. Would you consider that as a good design? – MKD Sep 02 '20 at 02:46
  • 2
    @Pokloha no, defining strings in your program that relate to your enum is not redundant. As was mentioned previously, you can think of enums as an alias for a number that improves readability. There is no way to reconcile that number into a string other than make an array of strings which express that number. Towards this being a good or bad design, it is what it is. Sometimes vendors will provide a toString or errstr function which does this translation for you, but even then, it may be desirable to create your own string that you can customize to your library. – Alex Baum Sep 02 '20 at 03:31

1 Answers1

0

The least-clever approach is to allocate some string constants that line up with the enumeration and index into it using the enumeration:

#include <stdio.h>

typedef enum {
   WIFI_START,
   WIFI_DIS,
   WIFI_CON
} STATUS;

const char *status[] = {"WIFI_START", "WIFI_DIS", "WIFI_CON"};

void eventHandler(int event_id) {
    printf("%s is triggered", status[event_id]);
}

int main() {
    eventHandler(WIFI_DIS);
    return 0;
}

I prefer this over a macro because, debugging/development utilities aside, program logic should be decoupled from the names used by the program to represent data. In other words, the program shouldn't behave differently based on variable name characteristics; it should be possible to minify, obfuscate or refactor the source code and be guaranteed you'll still get the same output.

ggorlen
  • 44,755
  • 7
  • 76
  • 106