Hello all.
Is it possible to convert an enum member variable to a string?
This would be useful in some cases...
Hello all.
Is it possible to convert an enum member variable to a string?
This would be useful in some cases...
If you are sufficiently bored, you can write a function that accepts an enum as an argument and returns a string. But there is no default conversion.
If you are looking to get the text names in an enum (these are used a lot for errors, etc), you can write a function with a switch/case inside based on the enum, that returns a string.
It is very often useful. I use a short perl script that you can feed the enum source code into and have it spit out a switch case in C based on the values. They can be very long, that saves much copy pasting.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
Yeah, no simple way to have it.
But on the sunny side, you can overload operator<< for the enum
Side question: doesn't the standard say that any two enum values ORed together are also valid values for the enum variable (e.g when used as bitfields)?Code:#include <iostream> #include <cassert> enum X { a, b }; std::ostream& operator<<(std::ostream& os, X x) { switch (x) { case a: return os << "a"; case b: return os << "b"; } assert(false && "wrong enum value"); } int main() { X x = a; std::cout << a; }
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Thanks for the replies.
Yes, I was looking for a way to get the string names of the member variables of an enum. I was hoping that there was a function generic enough to accept any enum, and return the text name of any given variable of the enum. Of course I had already considered writing a function for handling specifically the enum I want to do this with (the code would be easy enough), but I was hoping for a function which could handle any enum. I guess that's not possible though.
Yes, that would be certainly useful. Any chance you would let me have the source code of that perl script?It is very often useful. I use a short perl script that you can feed the enum source code into and have it spit out a switch case in C based on the values. They can be very long, that saves much copy pasting.
I really wish we could do this in C++ as it is useful in a lot of situations. This is one thing, IMO, that is lacking from the language - but if you could convert enums to strings it might introduce other issues related to using enumerations that I can't think of off the top of my head. ORing certainly would be one of them.
Hmm...I'm thinking I might be able to write a simple C++ program which can open a .cpp or .h file, read it line by line, checking each for an string 'enum'. And each time it finds it, it will read every line (parsing the string to include only the names of the enum values, instead of also the '=' sign and the number values), until it finds the terminating semicolon following. Each enum value name will be stored in a separate string (probably in an array).
It will then write a function for retrieving one of those string values from the array (using an exact copy of the original enum as a paramater argument). When the user wants to retrieve a specific enumeration value from this function, he will simply call it up, passing in the name of the enumeration value he wants to retrieve as a string.
The code that the program will write to file for each enum will look something like this:
Then the user can simply include the generated header file in his or hers source file, and call the function as needed.Code:class CNameOfEnumToString { public: CNameOfEnumToString(); const char getStringOfEnumValueX(NameOfEnum enumVar); enum NameOfEnum { NameOfEnumValue1, NameOfEnumValue2, NameOfEnumValue3 }; private: const char NameOfArrayForHoldingEnumValues[]; }; CenumToString::CenumToString() { NameOfArrayForHoldingEnumValues[0] = "NameOfEnumValue1"; NameOfArrayForHoldingEnumValues[1] = "NameOfEnumValue2"; NameOfArrayForHoldingEnumValues[2] = "NameOfEnumValue3"; } const char CenumToString::getStringOfEnumValueX(NameOfEnum enumVar) { if (enumVar == NameOfEnumValue1) { return NameOfArrayForHoldingEnumValues[0]; } if (enumVar == NameOfEnumValue2) { return NameOfArrayForHoldingEnumValues[1]; } if (enumVar == NameOfEnumValue3) { return NameOfArrayForHoldingEnumValues[2]; } }
Last edited by Programmer_P; 05-08-2010 at 11:50 AM.
The standard says:
(Note 4 gives details about 1's and 2's complement values.)For an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values of the underlying type in the range bmin to bmax, where bmin and bmax are, respectively, the smallest and largest values of the smallest bitfield that can store emin and emax.4) It is possible to define an enumeration that has values not defined by any of its enumerators.
I take it mean that the following is guaranteed to work (with respect to the underlying type and all):
Depending on whether it makes sense for a particular enum or not (it does for X), you'd also need to be able to handle this. Should be perfectly possible to handle, except not with a switch (e.g the string representation could be "b | c").Code:enum X {a =1, b = 2, c = 4 }; X enum_value = X( b | c );
----
Programmer_P: I think, to an extent, macro magic is possible to declare an enum and a conversion to string at the same time.
Last edited by anon; 05-08-2010 at 11:44 AM.
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Okay, this is very simple so it should be easy enough to modify even if you don't use perl (eg, right now the output uses strcpy() and not C++, etc):
Just create a file containing the enum without the containing block {}, eg:Code:#!/usr/bin/perl -w use strict; die "Input file required" if (!defined($ARGV[0])); if (defined $ARGV[1]) { open(OUT,">".$ARGV[1]) || die "Couldn't open ".$ARGV[1].": $!"; } else { open (OUT, ">&STDOUT") } open(IN,"<".$ARGV[0]) || die "Couldn't open ".$ARGV[0]."$!"; print OUT "switch (VAR) {\n"; while (<IN>) { (my $enum = $_) =~ s/[\s|\t]//g; $enum =~ s/,.*$//; print OUT "\tcase ($enum):\n" ."\t\tstrcpy(STR_HERE,\"$enum\");\n" ."\t\tbreak;\n"; } print OUT "\tdefault:\n}\n"; close(IN); close(OUT);
The comments will be discarded. This is a very common format to cut n' paste, if there are no line breaks or there are comments starting the line it will screw up. This produces output like this:Code:ONE, /* comment */ TWO, THREE, /*comment */ FOUR
So you can search and replace "VAR" and "STR_HERE". If you include a second file name argument, the output is into that file, otherwise it's on STDOUT.Code:switch (VAR) { case (ONE): strcpy(STR_HERE,"ONE"); break; case (TWO): strcpy(STR_HERE,"TWO"); break; case (THREE): strcpy(STR_HERE,"THREE"); break; case (FOUR): strcpy(STR_HERE,"FOUR"); break; default: }
Last edited by MK27; 05-08-2010 at 11:44 AM.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
Thanks.