(转载)C++中枚举与字符串相互转换
来源:互联网 发布:ubuntu安装qq的命令 编辑:程序博客网 时间:2024/06/11 00:39
C++中枚举与字符串相互转换
前言
有的时候我们喜欢使用一些外部的文件保存管理一些配置信息,这些配置文件大多都是文本格式例如ini,xml等,这样方便编辑和管理。因此在使用的过程中必然会遇到各种字符串转换问题。
最常见的便是将字符串的数字转换为对应的整形(integer)或者浮点(float),如果遇到枚举类型,可能便会想当做是整形来处理,但觉得不是特别理想。如果能有办法直接转换为枚举会方便很多。
案例
一个简单的配置文件:
1
[config]
2
fooInt = 10
3
fooFloat = 2.5
4
fooEnum = cpp
在C++里面有枚举:
1
enum
ProgLang
2
{
3
e_cpp,
4
e_java,
5
e_csharp
6
};
如果对于前面两个数值,可以很简单的读取,例如:
1
Config cfg;//Config 类见<<C++编写Config类读取配置文件>>
2
cfg.Load(
"config.ini"
);
3
4
int
fooInt = cfg.GetValue<
int
>(
"fooInt"
);
5
float
fooFloat = cfg.GetValue<
float
>(
"fooFloat"
);
对于后面那个枚举,可能就稍微麻烦一点:
1
ProgLang fooEnum;
2
const
char
* rawData = cfg.GetValue<
const
char
*>(
"fooEnum"
);
3
if
(
strcmp
(rawData,
"cpp"
)) fooEnum = e_cpp;
4
else
if
(
strcmp
(rawData,
"java"
)) fooEnum = e_java;
5
else
if
(
strcmp
(rawData,
"csharp"
)) fooEnum = e_csharp;
如果直接在配置文件里面不保存”cpp“字符串而直接保存枚举值,这里便可以当整形取出来再做类型转换。不过这样不安全,也不好维护,如果枚举内部的定义发生了变化,外部保存的数据自然也就会失效出错。
解决方案
C++没有(也不可能会有)反射机制,枚举成员在编译以后也已经变成了纯粹的数值,失去了名字。所以想使用字符串作为搜索依据,必须为枚举保留一份名字信息,例如:
1
enum
ProgLang
2
{
3
e_cpp,
4
e_java,
5
e_csharp
6
};
7
const
char
* ProgLangNames[] = {
"cpp"
,
"java"
,
"csharp"
};
这个字符串数组只能预先写好,无论是手动还是通过工具自动生成。然后可以在这个字符串数组里面搜索目标字符串,将找到的结果下标转换为对应的枚举值即可,例如:
1
for
(
int
i = 0; i <
sizeof
(ProgLangNames) /
sizeof
(ProgLangNames[0]); ++i)
2
{
3
if
(
strcmp
(rawData, ProgLangNames[i]))
4
{
5
fooEnum =
static_cast
<ProgLang>(i);
6
break
;
7
}
8
}
枚举关联字符串
解决方案找到了,随之而来的问题就是如何将枚举与所需要的字符串查找表联系起来。如有多个枚举:
01
enum
ProgLang
02
{
03
e_cpp,
04
e_java,
05
e_csharp
06
};
07
const
char
* ProgLangNames[] = {
"cpp"
,
"java"
,
"csharp"
};
08
09
enum
ScriptLang
10
{
11
e_lua,
12
e_actionscript,
13
e_javascript
14
};
15
const
char
* ScriptLangNames[] = {
"lua"
,
"actionscript"
,
"javascript"
};
枚举不像类或结构体可以定义自己的成员变量,所以查找表只能在外部定义,通过实例化模板类来将他们相互联系起来。例如:
1
<
template
EnumType>
2
struct
SEnumName
3
{
4
static
const
char
* List[];
5
}
这定义了一个查找表的模板结构体,然后将之前的代码改造为:
01
enum
ProgLang
02
{
03
e_cpp,
04
e_java,
05
e_csharp
06
};
07
const
char
* SEnumName<ProgLang>::List[] =
08
{
09
"cpp"
,
10
"java"
,
11
"csharp"
12
};
13
14
enum
ScriptLang
15
{
16
e_lua,
17
e_actionscript,
18
e_javascript
19
};
20
const
char
* SEnumName<ScriptLang>::List[] =
21
{
22
"lua"
,
23
"actionscript"
,
24
"javascript"
25
};
然后便可以实现字符串转枚举的功能:
01
template
<
typename
EnumType>
02
EnumType ConvertStringToEnum(
const
char
* pStr)
03
{
04
EnumType fooEnum =
static_cast
<EnumType>(-1);
05
int
count =
sizeof
(SEnumName<EnumType>::List) /
06
sizeof
(SEnumName<EnumType>::List[0]);
07
for
(
int
i = 0; i < count; ++i)
08
{
09
if
(
strcmp
(rawData, SEnumName<EnumType>::List[i]))
10
{
11
fooEnum =
static_cast
<ProgLang>(i);
12
break
;
13
}
14
}
15
return
fooEnum;
16
}
这样一来,最开始的问题就可以简化为:
1
ProgLang fooEnum = cfg.GetValue<ProgLang>(
"fooEnum"
);
有了这种方式,自然枚举反转回字符串也很容易了,就不再赘述了。
转载出处: http://a.vifix.us/blog/cpp-convert-string-enum
- (转载)C++中枚举与字符串相互转换
- (转)C++中枚举与字符串相互转换
- objective-c 中字符串与日期相互转换
- C/C++中ASCII与Unicode字符串相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- C/C++中字符串与数字相互转换
- objective-c 中字符串与日期相互转换
- C/C++中字符串与数值相互转换
- C语言中字符串与整数的相互转换
- 怎样实现字符串与枚举量的相互转换
- C#:数值与字符串之间相互转换
- 令人兴奋的sql server 2005 分页功能
- SQL Server数据库的查询优化及分页算法(3)(转)
- SQL Server 存储过程的分页(转)
- 常用编程小技巧总结
- 使用JXTA技术建立P2P网络(转)
- (转载)C++中枚举与字符串相互转换
- 火狐浏览器使用:缓存查看工具 Cache Viewer,书签管理
- 点对点(P2P)多线程断点续传的实现(转)
- P2P技术穿透NAT可行性讨论
- vs2005编译DNW050A
- P2P之UDP穿透NAT的原理与实现(附源代码)(转)
- 2011年目标
- JSP学习笔记(2)--Expression Language
- 'mysql' 不是内部或外部命令,也不是可运行的程序,或批处理文件。