954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

C++ Help with enum and cin

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,

bobr_1013
Light Poster
27 posts since Apr 2005
Reputation Points: 10
Solved Threads: 0
 

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
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

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
#include
#include
#include
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<<"--- "<

bobr_1013
Light Poster
27 posts since Apr 2005
Reputation Points: 10
Solved Threads: 0
 

>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.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You