0

I'm trying to make a small poker program. I have one little problem here. How can my enum hold string instead of char?

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;
enum mark{Hearts="Hearts",Diamonds='D', Spades='S', Clubs='C'};
char cards[5];
string marks[5];

int main()
{
    srand(time(NULL));
    cout<<"Welcome to the Classic Poker!\n";
    cards[0]='4';
    marks[0]=Hearts;
    cout<<"cards[0]="<<cards[0]<<endl;
    cout<<"marks[0]="<<marks[0]<<endl;
}

At this point it gives me a compiler error: "main.cpp|7|error: enumerator value for 'Hearts' is not an integer constant|".

Maksim Solovjov
  • 3,147
  • 18
  • 28
  • 2
    You can't do that. An enum must contain integral types. – dmeglio Sep 05 '15 at 19:07
  • Thanks! I though I was doing something wrong. So I must to find another way to solve this issue. – AleksandarAngelov Sep 05 '15 at 19:10
  • You probably want something like [this](http://stackoverflow.com/questions/3342726/c-print-out-enum-value-as-text). – Baum mit Augen Sep 05 '15 at 19:10
  • Why not using the enum values consistently like `enum mark{Hearts='H',Diamonds='D', Spades='S', Clubs='C'};`? – πάντα ῥεῖ Sep 05 '15 at 19:12
  • Because I would like to have output like "4 Hearts", not "4 H", I know even with 'H' it is possible using 'switch' to get "Hearts" but that is a longer way. – AleksandarAngelov Sep 05 '15 at 19:26
  • You can also try using this library (disclaimer: I am the author): https://github.com/aantron/better-enums. You would do `ENUM(mark, int, Hearts, Diamonds, Spades, Clubs)`, then if `mark m = mark::Hearts;`, `m._to_string()` is `"Hearts"` and `cout << m` prints "Hearts". – antron Sep 07 '15 at 06:01

2 Answers2

3

It is simply not possible, an enumerator is an integral.

What you can easily do, however, is build a simple function which associates each enumerator to a string:

enum mark { Hearts, Diamonds, Spades, Clubs };

std::string to_string(mark const m) {
    switch (m) {
    case Hearts: return "Hearts";
    case Diamonds: return "Diamonds";
    case Spades: return "Spades";
    case Clubs: return "Clubs";
    }
    throw std::runtime_error("Unknown value");
}
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • This is what I though after realizing that I am not able to use strings in enum. Unfortunately I am not able to vote up because of my reputations but it is helpful. – AleksandarAngelov Sep 05 '15 at 19:23
  • @AleksandarAngelov: don't worry about it, I've got more than I know what to do with anyway, and as long as you contribute to the site you'll soon find yourself with enough to do pretty much anything as well. – Matthieu M. Sep 05 '15 at 19:29
  • now I have 15 reputations and I vote you up, I have not forget what u have done to be – AleksandarAngelov Sep 14 '15 at 21:19
  • @AleksandarAngelov: Thanks for taking the time to come back! – Matthieu M. Sep 15 '15 at 06:07
2

You can't. What you could do is initialize an array of strings, and use the enumerated type to index it. Note that i've also changed marks to the enumerated type (I believe that's what you meant, so it needs to be defined after the enum is, or you should use a typedef.

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;
enum mark{Hearts=0,Diamonds, Spades, Clubs} marks[5];
string mark_names[4] = {"Hearts","Diamonds", "Spades", "Clubs"};
char cards[5];

int main()
{
    srand(time(NULL));
    cout<<"Welcome to the Classic Poker!\n";
    cards[0]='4';
    marks[0]=Hearts;
    cout<<"cards[0]="<<cards[0]<<endl;
    cout<<"marks[0]="<<mark_names[marks[0]]<<endl;
}

Now if you don't like typing the names twice, and you're willing to do some macro tricks, here's a neat options - define the names in an external file, and include them like this:

enum mark{
#define DEF_MARK(a) a,
#include "marks.def"
} marks[5];

string mark_names[4] = {
#define DEF_MARK(a) #a,
#include "marks.def"
};

where marks.def is:

DEF_MARK(Hearts)
DEF_MARK(Diamonds)
DEF_MARK(Spades)
DEF_MARK(Clubs)
#undef DEF_MARK

One last improvement i'd suggest is adding a last DEF_MARK(MAX_MARK), and then using MAX_MARK in your program as the array size (instead of the nasty hardcoded 4)

Leeor
  • 19,260
  • 5
  • 56
  • 87