tags:

views:

152

answers:

5

I have a file with values like: START and STOP. I also have the following enum declared:

enum Type {
    START,
    STOP
};

I'm trying to set the enum equal to the first value in the file with something like this:

enum Type foo;

ifstream ifile;
ifile.open("input.txt");

ifile >> foo;

I'm getting the error: no match for ‘operator>>’ in ‘ifile >> foo’.

How do I go about doing this correctly?

A: 

The quickest thing to do is to read in an int and cast it to your Type enum.

popester
I don't have control over the input files so I need to be able to do everything on the code end of things.
blcArmadillo
That's what I'm saying.int i;ifile >> i;foo = (Type) i;
popester
Humm... I tried writing a simple program to test what you're saying and it didn't seem to work. I've posted details as an "answer" to this question. If you could check it out I'd really appreciate it. Thanks.
blcArmadillo
Unless you can trust that some one will never ever ever ever type something stupid (e.g. a value out of range of your enum), this approach should be avoided as you could easily end up with a non-sensible value.
Stephen Edmonds
A: 

@popester

I'd post this as a response but from past experience code doesn't translate too well in post replies on SO.

I just wrote up the following short program to test what you suggested:

#include <iostream>
#include <fstream>

using namespace std;

int main() {
    enum Type {
        START,
        STOP
    };

    int bar;
    enum Type foo;

    ifstream ifile;
    ifile.open("input.txt");

    ifile >> bar;

    foo = (Type) bar;
    cout << "bar: " << bar << endl;

    cout << "foo: " << foo << endl;
}

Below is my input.txt file:

STOP

I compiled and ran the program and it output the following:

bar: -1207974988
foo: -1207974988

Am I just misunderstanding what you're suggesting? If you could lead me in the right direction that would be great. Thanks for your help.

blcArmadillo
I'm sorry, I misunderstood the file representation. I assumed that the file had '1' or '0' as the contents, not the string. C/C++ doesn't have a good answer for what you're trying to do, except for manually maintaining a constant representation of the string. If you can get away with using CLR/C++ you can do fancy enum parsing, but C++ has no native support for parsing enums based on the name of the value.
popester
+1  A: 

The stream insertion operator is not overloaded for user defined types. You can either define one for your enum object of type Type or use one of the existing overloads for reading unsigned char or bool and then change the value to your enum.

dirkgently
+1  A: 

http://condensedcpp.com/Enums.html

std::istream& operator >> (std::istream& i, Season& season)
{
    season = SPRING;
    std::string value;
    if (i >> value) {
        if (value == "Summer") {
            season = SUMMER;
        }
        else if (value == "Autumn") {
            season = AUTUMN;
        }
       else if (value == "Winter") {
            season = WINTER;
        }
    }
    return i;
}
navigator
+1  A: 

I've found for my particular situation that the following code is the best solution:

template <class T> T a2e(string c, const string a[], const int size) {
    for (int i=0; i < size; i++) {
        if (c == a[i]) {
            return static_cast<T>(i);
        }
    }
}

And would be used as follows:

enum StateType {START, STOP};
const int MAXVALUES = STOP+1;
const string stateNames[MAXVALUES] = {"START", "STOP"};

enum StateType state;

ifstream ifile;
ifile.open("input.txt");

ifile >> foo;
state = a2e <enum StateType> (foo, stateNames, MAXVALUES);

Hope this helps someone in the future. Thanks to everyone who made suggestions about how to tackle this problem.

blcArmadillo
Just a note on style: I'd prefer putting a NUMBER_OF_STATETYPES at the end of instead of declaring a separate, syntactically unrelated variable. In case more states are added later, it's less likely that the number of the enum values won't be updated.
mxp