2

The following is my code:

enum Color {red, blue};
enum Number {3,4};
enum Shape {circle, square};

struct article 
{
    enum Color color;
    enum Number number;
    enum Shape shape;
} article_1;

//assume I have the below for all three enums
std::istream& operator>>( std::istream& is, Color& I ) 
{
    int tmp ;
    if ( is >> tmp )
        i = static_cast<Color>( tmp ) ;
    return is ;
}

int main ()
{
    cout<<"Enter the Color : ";
    cin>>article_1.color;

    cout<<"Enter the Number : "; 
    cin>>article_1.number;

    cout<<"Enter the Shape : ";
    cin>>article_1.shape;

    return 0;
}

The code compiles without any errors. However, when the terminal pops up asking me to enter the color, when I enter red, the terminal disappears and I get an error saying Program.exe has exited with code 0(0x0). What am I doing wrong?

Christophe
  • 68,716
  • 7
  • 72
  • 138

2 Answers2

2

enums are a compile-level feature. Once the app is compiled, there are only numbers. The strings you put in an enum are replaced by numbers at the time the program is run.

You would have to cin a string and compare it to a runtime string (not an enum) to get what you need.

std::string x;
cin >> x;
if (x == "red") 
{
}

You can also create a std::map<std::string,int>. The comment by scohe001 also shows some ways.

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
  • Generally, colors are int collections. RGB for example. – Michael Chourdakis Jan 06 '20 at 20:48
  • Thank you for the answer, that worked. My follow up questions are 1. Is there anyway to equate x to color? like some sort of casting? 2. Let's say, I have variable x for color, y for number and z for shape. If the value of z is dependent on x and y (for example, if color is red and number is 4, then shape is circle), what parameters would I have to use for comparison? x or color? 3.Isn't also redundant to have two variables to save the same value? If I am using x, then what is the point of having another variable of type enum? – siri gowtham Jan 06 '20 at 20:54
  • Generally you need to learn more on class design, in which you learn about member functions and comparison operators to learn the proper way of implementation. Colors for example can be converted to RGB from HSL etc, so you only need 3 variables of RGB (and possibly alpha) and then you 'd use member functions to compare between another color struct that may be in HSL format. – Michael Chourdakis Jan 06 '20 at 21:09
  • Although I used colors in this example, I am looking for different implementations of enum. For example I want to define an enum for options in a menu etc. Do you recommend any material to understand member functions and comparison operators? – siri gowtham Jan 06 '20 at 22:11
  • @sirigowtham https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Michael Chourdakis Jan 06 '20 at 22:11
0

There is no intelligent conversion between strings and enums in C++.

Your input code doesn't work, because you read a int from the input stream and cast it to the color:

  • It could work if you would enter a valid integer corresponding to one of the enum's value encoding.
  • But if you enter a string, the input operation fails because of the incompatible type. The input stream gets in error and all subsequent operations on that stream will fail until you clear the error flags.

If you want to read a string, you need to take care of it. For example with the following code:

std::istream& operator>>( std::istream& is, Color& I ) 
{
    std::string tmp;
    if ( is >> tmp ) {
        for (auto&c:tmp)
            c=std::tolower(c);  
        if (tmp=="red") I = red; 
        else if (tmp=="blue") I = blue;   
        // but what happens if the string is invalid ???
    }
    return is ;
}
std::ostream& operator<<( std::ostream& os, Color& O ) 
{
    std::string tmp; 
    switch (O) {
        case red:  tmp="red"; break; 
        case blue: tmp="blue"; break; 
        default:   tmp="oops!!";
    }
    return os<<tmp ;
} 

Of course, this is only a naive example. In reality you'd probably have a std::map to hold the association between the string and the enum and vis versa.

Worth to know:

The enumerators in an enum can be mapped to integral values. By default, the first enumerator (red) is mapped to 0. THe following enumerators get a value that is 1 more than the preceding ones (i.e. blue would be 1).

But you are free to set a value (e.g. enum Color { red=2, green, blue=green+4 };). This is why it is legal to cast between an int and an enum. But be very careful when doing this because as soon as the integer does not match exactly an enumerator value, it can become complex.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Thank you, that worked. Does this mean I have to write this snippet for all 3 enums? Writeing a function won't work because all the parameters inside the enums are different. Is it possible to use a functionalists for all 3 enums? Second question is how would I be able to compare the values of the enum? Lets say I have the enum is a variable inside a struct str. I want to compare the enum value, if str.color != red , then cut<<"Not red". I get errors when I use != along with enum. How can I fix this? – siri gowtham Jan 07 '20 at 20:01
  • 1
    @sirigowtham 1) Indeed, you need to foresee this kind of conversion for all the different enum types that you'd create. Typically, you'd do this with a static map. But in real life application it's more complicated since user interface could be multilingual, and you would isolate such conversion in the UI layer. 2) If you compare two colors it should work ([demo](https://ideone.com/gDx1uI)). But you can't compare colors with strings if you don't have a conversion operator defined. – Christophe Jan 07 '20 at 21:04