How can I use "cin" to allow entry of an enum type in C++?

My code is as follows:

 enum Cards {TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, 
                   JACK, QUEEN, KING, ACE};

   Cards hand1 = ACE,
           hand2 =  ACE;


   cout<<"Player#1 - Pick a card (2 - A): ";
   cin>>hand1;

   cout<<"Player#2 - Pick a card (2 - A): ";
   cin>>hand2;

I'm getting a lot of syntax errors with this..

Any suggestions?

Thanks,

Recommended Answers

All 3 Replies

You need to define an operator>> that looks for an object of your enum:

#include <iostream>
#include <stdexcept>

using namespace std;

enum X { A, B, C };

istream& operator>> ( istream& in, X& x )
{
  int val;

  if ( in>> val ) {
    switch ( val ) {
    case A: case B: case C:
      x = X(val); break;
    default:
      throw out_of_range ( "Invalid value for type X" );
    }
  }

  return in;
}

int main()
{
  X x;

  try {
    cin>> x;
    cout<< x <<endl;
  } catch ( out_of_range& ex ) {
    cerr<< ex.what() <<endl;
  }
}

Narue,

I changed my code to the way your code is. I got a clean compile, but now when I want to display what I'm entering, I'm getting a numeric value:

Also (referring to my code) if I was to add hand2, do I also need to create a separate operator for that?

The following is the code:

#include <iomanip>
#include <iostream>
#include <fstream>
#include <stdexcept>
using namespace std;

enum Cards {TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};

istream& operator>> (istream& in, Cards& hand1)
  {
      int val;
      if (in>>val)
         {
             switch (val)
                {
                  case TWO:
                  case THREE:
                  case FOUR:
                  case FIVE:
                  case SIX:
                  case SEVEN:
                  case EIGHT:
                  case NINE:
                  case TEN:
                  case JACK:
                  case QUEEN:
                  case KING:
                  case ACE:
                     hand1 = Cards(val);
                     break;
                  default:
                     throw out_of_range ("*** Invalid Entry ***");
                  }                    


         }         
         return in;

  }          

int main()
{
   /*--------------------------------------
    * Initialize variables 
    *------------------------------------*/

   Cards hand1;      

   try {
   cout<<"Player#1 - Pick a card (2 - A): ";
   cin>>hand1;
   cout<<"--- "<<hand1<<endl;
   } catch (out_of_range& ex ) {
     cerr<<ex.what() <<endl;
   }

>but now when I want to display what I'm entering, I'm getting a numeric value
Well sure, what were you expecting? The very definition of an enumeration is a distinct type representing a list of named integral constants. The internal representation is basically int, so when you print the value of an enum instance, you'll get a number.

However, you can write an operator<< to print the name of the constant if you want:

#include <iostream>
#include <stdexcept>

using namespace std;

enum X { A, B, C };

istream& operator>> ( istream& in, X& x )
{
  int val;

  if ( in>> val ) {
    switch ( val ) {
    case A: case B: case C:
      x = X(val); break;
    default:
      throw out_of_range ( "Invalid value for type X" );
    }
  }

  return in;
}

ostream& operator<< ( ostream& out, const X& x )
{
  switch ( x ) {
  case A: out<<"A";
  case B: out<<"B";
  case C: out<<"C";
  }

  return out;
}

int main()
{
  X x;

  try {
    cin>> x;
    cout<< x <<endl;
  } catch ( out_of_range& ex ) {
    cerr<< ex.what() <<endl;
  }
}

>if I was to add hand2, do I also need to create a separate operator for that?
No, the operator is overloaded for the type, so as long as hand 1 and hand2 are objects of Cards, the operator will work with them both.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.