C++: Print Out Enum Value as Text

Print text instead of value from C enum

Enumerations in C are numbers that have convenient names inside your code. They are not strings, and the names assigned to them in the source code are not compiled into your program, and so they are not accessible at runtime.

The only way to get what you want is to write a function yourself that translates the enumeration value into a string. E.g. (assuming here that you move the declaration of enum Days outside of main):

const char* getDayName(enum Days day) 
{
switch (day)
{
case Sunday: return "Sunday";
case Monday: return "Monday";
/* etc... */
}
}

/* Then, later in main: */
printf("%s", getDayName(TheDay));

Alternatively, you could use an array as a map, e.g.

const char* dayNames[] = {"Sunday", "Monday", "Tuesday", /* ... etc ... */ };

/* ... */

printf("%s", dayNames[TheDay]);

But here you would probably want to assign Sunday = 0 in the enumeration to be safe... I'm not sure if the C standard requires compilers to begin enumerations from 0, although most do (I'm sure someone will comment to confirm or deny this).

C++: Print out enum value as text

Using map:

#include <iostream>
#include <map>
#include <string>

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
static std::map<Errors, std::string> strings;
if (strings.size() == 0){
#define INSERT_ELEMENT(p) strings[p] = #p
INSERT_ELEMENT(ErrorA);
INSERT_ELEMENT(ErrorB);
INSERT_ELEMENT(ErrorC);
#undef INSERT_ELEMENT
}

return out << strings[value];
}

int main(int argc, char** argv){
std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
return 0;
}

Using array of structures with linear search:

#include <iostream>
#include <string>

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
#define MAPENTRY(p) {p, #p}
const struct MapEntry{
Errors value;
const char* str;
} entries[] = {
MAPENTRY(ErrorA),
MAPENTRY(ErrorB),
MAPENTRY(ErrorC),
{ErrorA, 0}//doesn't matter what is used instead of ErrorA here...
};
#undef MAPENTRY
const char* s = 0;
for (const MapEntry* i = entries; i->str; i++){
if (i->value == value){
s = i->str;
break;
}
}

return out << s;
}

int main(int argc, char** argv){
std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
return 0;
}

Using switch/case:

#include <iostream>
#include <string>

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
const char* s = 0;
#define PROCESS_VAL(p) case(p): s = #p; break;
switch(value){
PROCESS_VAL(ErrorA);
PROCESS_VAL(ErrorB);
PROCESS_VAL(ErrorC);
}
#undef PROCESS_VAL

return out << s;
}

int main(int argc, char** argv){
std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
return 0;
}

How to print the enum value from its index?

The enum constants names are not known after your program has been compiled. To get the names, you can create an array so you can do the reverse lookup. Example:

enum foo {
Apple,
Banana,
Orange
};

const char* revfoo[]{ "Apple", "Banana", "Orange" };

std::cout << revfoo[Apple] << '\n'; // Prints "Apple"

Note: This works for enums starting at 0 and has no gaps. If your enums are not zero-based or has gaps, you could use an unordered_map instead.

#include <string>
#include <unordered_map>

std::unordered_map<foo, std::string> revfoo {
{Apple, "Apple"},
{Banana, "Banana"},
{Orange, "Orange"}
};

std::cout << revfoo[Apple] << '\n'; // Prints "Apple"

Can I display the value of an enum with printf()?

As a string, no. As an integer, %d.

Unless you count:

static char* enumStrings[] = { /* filler 0's to get to the first value, */
"enum0", "enum1",
/* filler for hole in the middle: ,0 */
"enum2", "enum3", .... };

...

printf("The value is %s\n", enumStrings[thevalue]);

This won't work for something like an enum of bit masks. At that point, you need a hash table or some other more elaborate data structure.

c++ Print an enum value

Apart from making your constructor and print function public, you should also know that enum class is not implicitly convertible to int. So you could either manually convert it to int in the print function:

std::cout << static_cast<int>(_color);

or overload the output operator for the Color:

std::ostream& operator<<(std::ostream& o, Color c)
{
std::cout << static_cast<int>(c);
return o;
}

This way, you could do some better output for your color - perhaps output a string representation of your enum values.

Here's a live example on cpp.sh

How to convert enum names to string in c

One way, making the preprocessor do the work. It also ensures your enums and strings are in sync.

#define FOREACH_FRUIT(FRUIT) \
FRUIT(apple) \
FRUIT(orange) \
FRUIT(grape) \
FRUIT(banana) \

#define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRING(STRING) #STRING,

enum FRUIT_ENUM {
FOREACH_FRUIT(GENERATE_ENUM)
};

static const char *FRUIT_STRING[] = {
FOREACH_FRUIT(GENERATE_STRING)
};

After the preprocessor gets done, you'll have:

enum FRUIT_ENUM {
apple, orange, grape, banana,
};

static const char *FRUIT_STRING[] = {
"apple", "orange", "grape", "banana",
};

Then you could do something like:

printf("enum apple as a string: %s\n",FRUIT_STRING[apple]);

If the use case is literally just printing the enum name, add the following macros:

#define str(x) #x
#define xstr(x) str(x)

Then do:

printf("enum apple as a string: %s\n", xstr(apple));

In this case, it may seem like the two-level macro is superfluous, however, due to how stringification works in C, it is necessary in some cases. For example, let's say we want to use a #define with an enum:

#define foo apple

int main() {
printf("%s\n", str(foo));
printf("%s\n", xstr(foo));
}

The output would be:

foo
apple

This is because str will stringify the input foo rather than expand it to be apple. By using xstr the macro expansion is done first, then that result is stringified.

See Stringification for more information.



Related Topics



Leave a reply



Submit