Convert enum member variable to string?

This is a discussion on Convert enum member variable to string? within the C++ Programming forums, part of the General Programming Boards category; Hello all. Is it possible to convert an enum member variable to a string? This would be useful in some ...

  1. #1
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Question Convert enum member variable to string?

    Hello all.
    Is it possible to convert an enum member variable to a string?
    This would be useful in some cases...

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    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.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    you can write a function that accepts an enum as an argument and returns a string.
    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

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Yeah, no simple way to have it.

    But on the sunny side, you can overload operator<< for the enum

    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;
    }
    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)?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by anon View Post

    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)?
    I don't have my standard on me, but I'm fairly certain the answer is "no". (E.g., if the valid values are 0 through 4, what should 4|2 represent?)

  6. #6
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Thanks for the replies.
    Quote Originally Posted by MK27 View Post
    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.
    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.
    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.
    Yes, that would be certainly useful. Any chance you would let me have the source code of that perl script?

  7. #7
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,590
    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.

  8. #8
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    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:

    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];
      }
    
    }
    Then the user can simply include the generated header file in his or hers source file, and call the function as needed.
    Last edited by Programmer_P; 05-08-2010 at 11:50 AM.

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The standard says:

    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.
    (Note 4 gives details about 1's and 2's complement values.)

    I take it mean that the following is guaranteed to work (with respect to the underlying type and all):

    Code:
    enum X {a =1, b = 2, c = 4 };
    
    X enum_value = X( b | c );
    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").

    ----

    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.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Programmer_P View Post
    Yes, that would be certainly useful. Any chance you would let me have the source code of that perl script?
    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):

    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);
    Just create a file containing the enum without the containing block {}, eg:
    Code:
            ONE,    /* comment */
            TWO,
            THREE,   /*comment */
            FOUR
    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:
    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:
    }
    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.
    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

  11. #11
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Thanks.

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,411
    Not tested, but how about some macro trickery?
    Code:
    #define ENUM_NAME(x) ##x
    std::cout << ENUM_NAME(MyEnum);
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Oct 2006
    Posts
    2,266
    Quote Originally Posted by Elysia View Post
    Not tested, but how about some macro trickery?
    Code:
    #define ENUM_NAME(x) ##x
    std::cout << ENUM_NAME(MyEnum);
    that works great as long as you send the LITERAL string of the enum value name. if it comes in as a function parameter, and then you pass it to that macro, it breaks by returning the name of the variable passed to it.

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,411
    True, not a perfect solution.
    But we could expand this by making our own enum type.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to convert string into LPCWSTR
    By krishnampkkm in forum C++ Programming
    Replies: 2
    Last Post: 06-15-2009, 06:02 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Replies: 10
    Last Post: 08-17-2005, 11:17 PM
  4. lvp string...
    By Magma in forum C++ Programming
    Replies: 4
    Last Post: 02-26-2003, 11:03 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21