Compare Enum with String

Voyhkah

Undead
Joined
Apr 25, 2009
Messages
1,444
Location
Earth
I have created this Enum:

Code:
enum CivilianUnitTypes
{
	NO_CIVILIAN_UNIT = -1,
	CIVILIAN_UNIT_MISSIONARY,
	CIVILIAN_UNIT_WORKER,
	CIVILIAN_UNIT_SETTLER,
	CIVILIAN_UNIT_GREAT_PERSON,
};

I have some XML tags where I input a CivilianUnitType and it does something. The variables in CvInfos are stored as ints. The question is, how do I convert the string to the enum?

I have this code:

Code:
int CvGlobals::getCivilianUnitType(CvString szTextVal) const
{
	 for (int iI = 0; iI <= NUM_CIVILIAN_UNIT_TYPES; iI++)
	{
		if ((CivilianUnitTypes)iI == szTextVal)
		{
			 return iI;
		}
	}
}

Clearly, the == operator doesn't cover it, so what can do this?
 
It is a long time since I coded C++, 3 years and counting :) but shouldn't that last comma in the enum not be there?

Code:
enum CivilianUnitTypes
{
	NO_CIVILIAN_UNIT = -1,
	CIVILIAN_UNIT_MISSIONARY,
	CIVILIAN_UNIT_WORKER,
	CIVILIAN_UNIT_SETTLER,
	CIVILIAN_UNIT_GREAT_PERSON
};

And shouldn't the brackets be about iI not the enum name

Code:
	if (CivilianUnitTypes[B][COLOR="Red"]([/COLOR][/B]iI[B][COLOR="Red"])[/COLOR][/B] == szTextVal)
 
@DH - The last comma can be there. It changes nothing. Both (CivilianUnitTypes)iI and CivilianUnitTypes(iI) are possible (they do the same thing - cast iI to CivilianUnitTypes), but the former is more commonly used (at least in the code I'm familiar with).

@Voyhkah - There's no built in feature in C++ to compare an enum value to its string representation (unlike in C#, for example). The way it's done in Civ 4 is that you define an info type for this enum, and the order in the XML matches the order in the enum. And then the 'type' string representation in the XML is used as a key to access the index in the XML, and therefore the value of the enum.

For example, WorldSizeTypes enum matches the WorldInfo XML, the enum YieldTypes matches the YieldInfo XML etc.
 
EDIT:

I came up with a less-than-optimal fix, but it works.

Code:
int CvGlobals::getCivilianUnitType(CvString szTextVal) const
{
	if (szTextVal == "CIVILIAN_UNIT_MISSIONARY")
		return 0;

	else if (szTextVal == "CIVILIAN_UNIT_WORKER")
		return 1;

	else if (szTextVal == "CIVILIAN_UNIT_SETTLER")
		return 2;

	else if (szTextVal == "CIVILIAN_UNIT_GREAT_PERSON")
		return 3;

	else
		return -1;

}
 
That won't work, since you're comparing pointers, not actual strings.

You should use strcmp (which returns 0 if the strings are equal):
(I also changed the function to return the enum type, but you can use your int version. Just make sure to update the function if you change the order of the enum!)
Code:
CivilianUnitTypes CvGlobals::getCivilianUnitType(CvString szTextVal) const
{
	if (strcmp(szTextVal, "CIVILIAN_UNIT_MISSIONARY") == 0)
		return CIVILIAN_UNIT_MISSIONARY;

	else if (strcmp(szTextVal, "CIVILIAN_UNIT_WORKER") == 0)
		return CIVILIAN_UNIT_WORKER;

	else if (strcmp(szTextVal, "CIVILIAN_UNIT_SETTLER") == 0)
		return CIVILIAN_UNIT_SETTLER;

	else if (strcmp(szTextVal, "CIVILIAN_UNIT_GREAT_PERSON") == 0)
		return CIVILIAN_UNIT_GREAT_PERSON;

	else
		return NO_CIVILIAN_UNIT;

}
 
I use int because this method is mainly used for reading XML. Multiple infos have XML tags for CivilianUnitTypes, including Units, Buildings, and Promotions.
 
Back
Top Bottom