Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Print out enum value as text

Tags:

c++

enums

If i have an enum like this

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

Then i want to print out to console

Errors anError = ErrorA; cout<<anError;/// 0 will be printed 

but what i want is the text "ErrorA", can i do it without using if/switch?
And what is your solution for this?

like image 445
tiboo Avatar asked Jul 27 '10 10:07

tiboo


People also ask

How do I convert an enum to a string?

There are two ways to convert an Enum to String in Java, first by using the name() method of Enum which is an implicit method and available to all Enum, and second by using toString() method.

Can we use enum as string?

In a string enum, each member has to be constant-initialized with a string literal, or with another string enum member. While string enums don't have auto-incrementing behavior, string enums have the benefit that they “serialize” well.

Can I use enum as type?

You can do this because enums are compiled to JavaScript objects, so they also have a value representation in addition to being types. direction can therefore only be set to a member of the CardinalDirection enum.

Can I convert enum to string in C++?

There is no such direct function to do so. But we can create our own function to convert enum to string. We shall create a function that takes an enum value as the argument, and we manually return the enum names as a string from that function.


2 Answers

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;    } 
like image 88
SigTerm Avatar answered Oct 01 '22 06:10

SigTerm


Use an array or vector of strings with matching values:

char *ErrorTypes[] = {     "errorA",     "errorB",     "errorC" };  cout << ErrorTypes[anError]; 

EDIT: The solution above is applicable when the enum is contiguous, i.e. starts from 0 and there are no assigned values. It will work perfectly with the enum in the question.

To further proof it for the case that enum doesn't start from 0, use:

cout << ErrorTypes[anError - ErrorA]; 
like image 37
Igor Avatar answered Oct 01 '22 07:10

Igor