如何在C ++中使用ToString()枚举?在Java和C#中,我只需要调用ToString。
enum Colours
{
Red =0,
Green=1,
Blue=2
};
我需要创建一个字符串:“无效颜色”“+颜色+”'已选中。
答案 0 :(得分:20)
虽然这通常是通过开关完成的,但我更喜欢数组:
#include <iostream>
namespace foo {
enum Colors { BLUE = 0, RED, GREEN, SIZE_OF_ENUM };
static const char* ColorNames[] = { "blue", "red", "green" };
// statically check that the size of ColorNames fits the number of Colors
static_assert(sizeof(foo::ColorNames)/sizeof(char*) == foo::SIZE_OF_ENUM
, "sizes dont match");
} // foo
int main()
{
std::cout << foo::ColorNames[foo::BLUE] << std::endl;
return 0;
}
显式数组大小具有生成编译时的好处 错误应该枚举的大小,你忘了添加 适当的字符串。
或者,Boost库中有Boost.Enum。图书馆 尚未正式发布,但相当稳定并提供了什么 你要。我不会向新手推荐它。
答案 1 :(得分:15)
宏的小魔法怎么样:
#include <iostream>
#include <string>
#include <vector>
// http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c
std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
int start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
#define ENUM(name, ...)\
enum name \
{\
__VA_ARGS__\
};\
std::vector<std::string> name##Map = split(#__VA_ARGS__, ',');\
std::string toString(const name v) { return name##Map.at(v);}
ENUM(Color, Red,Green,Blue)
int main(int c, char**v)
{
std::cout << toString(Red) << toString(Blue);
return 0;//a.exec();
}
是的,我知道这很难看,你最好不要做这些事情
答案 2 :(得分:8)
这本质上是不可能的。
C ++枚举只是一组带有编译时名称的数字 在运行时,它们与普通数字无法区分。
您需要编写一个返回字符串的switch
语句。
答案 3 :(得分:3)
enum Color
{
Red =0,
Green=1,
Blue=2
};
std::string ColorMap[] = { "Red", "Green","Blue" };
使用ColorMap[c]
获取字符串表示形式:
std::string msg = "Invalid colour '" + ColorMap[c] + "' selected.";
但是,如果枚举的值不是连续的,那么您可以使用std::map
代替:
enum Color
{
Red = 0x1,
Green = 0x2,
Blue = 0x4,
Black = 0x8,
};
//C++11 only, as it uses std::initializer_list
std::map<Color, std::string> ColorMap = {
{Red, "Red"},
{Green, "Green"},
{Blue, "Blue"},
{Black, "Black"}
};
//same as before!
std::string msg = "Invalid colour '" + ColorMap[c] + "' selected.";
答案 4 :(得分:3)
我非常喜欢@ Lol4t0的宏观方法。
我将它扩展为能够从字符串转换枚举:
#include <iostream>
#include <string>
#include <vector>
// http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c
std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
int start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
#define ENUM(name, ...)\
enum name\
{\
__VA_ARGS__\
};\
static const int name##Size = (sizeof((int[]){__VA_ARGS__})/sizeof(int));\
static const vector<string> name##ToStringMap = split(#__VA_ARGS__, ',');\
const string name##ToString(const name value)\
{\
return name##ToStringMap.at(value);\
};\
map<string, name> name##ToFromStringMap(...)\
{\
map<string, name> m;\
name args[name##Size] = { __VA_ARGS__ };\
\
int i;\
for(i = 0; i < name##Size; ++i)\
{\
m[name##ToString(args[i])] = args[i];\
}\
return m;\
};\
static map<string, name> name##FromStringMap = name##ToFromStringMap(__VA_ARGS__);\
const name name##FromString(const string value, const name defaultValue)\
{\
if(name##FromStringMap.count(value) == 0)\
{\
return defaultValue;\
}\
return name##FromStringMap[value];\
};
用法:
ENUM(MyEnum, Value1, Value2)
void main()
{
string valueName = MyEnumToString(MyEnum::Value2);
MyEnum value = MyEnumFromString(valueName, MyEnum::Value1);
}
我不是C ++专家,所以让我知道你的想法或如何做得更好。
答案 5 :(得分:1)
你必须手动完成,即
const char* ToString(Colours co) {
switch(co) {
case Red:
return "Red";
// ...
}
}
也可以使用查找表。我也看到人们使用自定义脚本在源代码之上生成这些东西。
答案 6 :(得分:0)
您可以将名称存储在字符串数组中,并按enum
值编制索引。
enum Colours
{
Red =0,
Green=1,
Blue=2
};
char* names[3] = {"Red", "Green", "Blue"};
然后你可以打印:"Invalid colour '" + names[colour] + "' selected."
但是,如果不按顺序定义enum
值,则此方法可能不太有用。在这种情况下,这种方法会浪费内存。正如亚历山大盖斯勒所提到的那样,用switch
编写一个超过enum
值的函数会很有用。另一种选择可能是来自STL的map
。
答案 7 :(得分:0)
正如@FlopCoder所说:
enum Colours
{
Red =0,
Green=1,
Blue=2
};
char* ColourNames[] = { "Red", "Green", "Blue" };
int colour = Green;
printf( "Invalid colour '%s' selected.", ColourNames[ colour ] );
这当然只有在你的枚举从0开始并且是连续的时才会起作用 @ Nawaz的方式更多是 C ++ fashion 。