(转载)C++中枚举与字符串相互转换

2023-05-16

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 };

然后便可以实现字符串转枚举的功能:

view source print ?
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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(转载)C++中枚举与字符串相互转换 的相关文章

随机推荐

  • 【deepstream】deepstream调用opencv(c与c++联合编译)

    目的 在deepstream项目中调用opencv库 xff0c 丰富deepstream功能 xff08 如往deepstream加入kalman filter实现跟踪 xff09 操作环境 Ubuntu 18 04Qt Creatot
  • pycharm不能导入不同文件夹下的自定义模块

    文件目录结构如下所示 xff1a span class token operator span A1 span class token operator span span class token operator span B1 span
  • 【力扣】654. 最大二叉树

    题目概述 原题链接 相关节点定义 xff1a span class token comment Definition for a binary tree node struct TreeNode int val TreeNode left
  • 【力扣】114. 二叉树展开为链表

    题目概述 原题链接 树定义如下 xff1a span class token comment Definition for a binary tree node struct TreeNode int val TreeNode left T
  • 【力扣】725. 分隔链表

    题目概述 原题链接 链表定义如下 xff1a span class token comment Definition for singly linked list struct ListNode int val ListNode next
  • Angular应用开发中遇到的问题

    记录在开发Angular应用时遇到的问题以及解决方案 问题 3 前提 xff1a 在Angular应用的组件中使用响应式表单进行数据校验 xff0c 使用FormBuilder服务的 group 方法来构建一组FormControl实例 需
  • 浏览器插件解决跨域问题

    浏览器插件解决跨域问题 在前端进行调试时 xff0c 经常会遇到CORS问题 xff0c 在调试时 xff0c 可暂时使用浏览器插件解决跨域问题 浏览器 xff1a Microsoft Edge 插件搜索截图如下 xff1a 插件开启后 x
  • 洛谷P1591 阶乘数码(C语言)简单易懂

    题目描述 求 n n 中某个数码出现的次数 输入格式 第一行为 t t leq 10 t t 10 xff0c 表示数据组数 接下来 t 行 xff0c 每行一个正整数 n n leq 1000 n n 1000 和数码 aa 输出格式 对
  • 将java项目发布到maven中央仓库(踩坑大全)

    前言 xff1a 第一次将构件发布到中央仓库 xff0c 真的不是一件轻松的事情 xff0c 网络上有很多其他文章大都不会把坑帮你描述清楚 所以觉得非常有必要把些步骤记下来 xff0c 让大家少走点弯路 一 maven中央仓库简介 相关内容
  • IOS-----手动创建Main界面

    1 删除info plist中的Main设置 2 创建MainViewController h 和MainViewController m xff08 1 xff09 布局界面 xff1a UIViewController instance
  • 【转载+修改】通过ssh 转发 X 图形界面

    转载自 xff1a http linux chinaitlab com administer 742586 html 过程精简如下 xff1a 1 配置你要链接到的机器的sshd 在 etc ssh sshd config 中将 Allow
  • [已解决]IDEA各文件类变成灰色的处理方法

    这是我遇到的问题 xff0c 创建好一个工程后 xff0c 各文件类变成了灰色 大概总结网上所说的的原因和处理方法 xff0c 可能是由于pom xml没有成功被解析 解决方法一 xff1a 右键点击这个pom文件 xff0c 选择将其添加
  • ubuntu安装opencv的正确方法

    本文介绍的是如何安装ubuntu下C 43 43 接口的opencv 1 安装准备 xff1a 1 1安装cmake sudo apt get install cmake 1 2依赖环境 sudo apt get install build
  • Ubuntu16.04升级 Ubuntu18.04

    Ubuntu16 04升级 Ubuntu18 04 1 更新资源 sudo apt get update sudo apt get upgrade sudo apt dist upgrade 2 安装update manager core
  • C++那些细节--typedef关键字

    一 简介 关于typedef关键字 xff0c 以前刚刚学C语言的时候 xff0c 用它来重定义结构体别名 之后的话就是在用函数指针的时候用过一些 xff0c 然而并不知道这个还有什么用处 今天花点时间总结一下typedef的细节 在计算机
  • python图片识别之tesseract

    经过两个下午的尝试 xff0c 终于搞出来了 xff1b 特记录下来备忘 xff1b 首先来看python代码识别图片 xff0c 这一段较为简单 xff1b span class token keyword from span PIL s
  • 游戏设计流失点总结

    xff08 1 xff09 直接彻底玩不懂 比如我之前的很多游戏 xff0c 玩家不知道怎么玩的挫败感会直接让ta去寻找更容易理解游戏 xff08 2 xff09 文字量太大 xff0c 懒得去学 有些游戏虽然有教程 xff0c 但是是长达
  • Rust安装(windows)

    windows安装Rust开发环境指南 Rust的安装非常简单 xff0c 官网下载安装包双击就能安装 xff0c 但是在windows上使用总是能遇到一些问题 xff0c 今天我们就来踩踩坑 设置安装路径 当你安装Rust的时候会发现没法
  • Debian安装中文包和输入法(针对中文无法显示)

    配置编码 xff1a python view plain copy aptitude install locales dpkg reconfigure locales 进入选择 xff1a zh CN GB2312 zh CN GBK GB
  • (转载)C++中枚举与字符串相互转换

    C 43 43 中枚举与字符串相互转换 前言 有的时候我们喜欢使用一些外部的文件保存管理一些配置信息 xff0c 这些配置文件大多都是文本格式例如ini xff0c xml等 xff0c 这样方便编辑和管理 因此在使用的过程中必然会遇到各种