如何将枚举类型变量转换为字符串?

2024-03-09

如何使 printf 显示枚举类型变量的值?例如:

typedef enum {Linux, Apple, Windows} OS_type; 
OS_type myOS = Linux;

我需要的是类似的东西

printenum(OS_type, "My OS is %s", myOS);

它必须显示字符串“Linux”,而不是整数。

我想,首先我必须创建一个值索引的字符串数组。但我不知道这是否是最好的方式。有可能吗?


当然,最简单的解决方案是为每个枚举编写一个函数来执行到字符串的转换:

enum OS_type { Linux, Apple, Windows };

inline const char* ToString(OS_type v)
{
    switch (v)
    {
        case Linux:   return "Linux";
        case Apple:   return "Apple";
        case Windows: return "Windows";
        default:      return "[Unknown OS_type]";
    }
}

然而,这是一场维护灾难。借助可与 C 和 C++ 代码一起使用的 Boost.Preprocessor 库,您可以轻松利用预处理器并让它为您生成此函数。生成宏如下:

#include <boost/preprocessor.hpp>

#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem)    \
    case elem : return BOOST_PP_STRINGIZE(elem);

#define DEFINE_ENUM_WITH_STRING_CONVERSIONS(name, enumerators)                \
    enum name {                                                               \
        BOOST_PP_SEQ_ENUM(enumerators)                                        \
    };                                                                        \
                                                                              \
    inline const char* ToString(name v)                                       \
    {                                                                         \
        switch (v)                                                            \
        {                                                                     \
            BOOST_PP_SEQ_FOR_EACH(                                            \
                X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE,          \
                name,                                                         \
                enumerators                                                   \
            )                                                                 \
            default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]";         \
        }                                                                     \
    }

第一个宏(以X_) 由第二个内部使用。第二个宏首先生成枚举,然后生成ToString函数接受该类型的对象并将枚举器名称作为字符串返回(由于显而易见的原因,此实现要求枚举器映射到唯一值)。

在 C++ 中你可以实现ToString功能作为operator<<相反,重载,但我认为需要显式的“更干净”ToString" 将值转换为字符串形式。

作为一个使用示例,您的OS_type枚举定义如下:

DEFINE_ENUM_WITH_STRING_CONVERSIONS(OS_type, (Linux)(Apple)(Windows))

虽然宏乍一看似乎需要大量工作,并且定义OS_type看起来很陌生,记住你必须编写一次宏,然后你可以将它用于每个枚举。您可以向其添加附加功能(例如,字符串形式到枚举的转换),而不会太麻烦,并且它完全解决了维护问题,因为您只需在调用宏时提供一次名称。

然后可以像正常定义一样使用枚举:

#include <iostream>

int main()
{
    OS_type t = Windows;
    std::cout << ToString(t) << " " << ToString(Apple) << std::endl;
}

这篇文章中的代码片段,从#include <boost/preprocessor.hpp>行,可以按发布的方式进行编译以演示解决方案。

这个特定的解决方案适用于 C++,因为它使用 C++ 特定的语法(例如,没有typedef enum) 和函数重载,但是用 C 语言也可以很简单地实现这一点。

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

如何将枚举类型变量转换为字符串? 的相关文章

随机推荐

  • Jquery - 将html字符串附加到变量中的html字符串

    我正在尝试创建一个 HTML 字符串 然后使用额外的 HTML 和属性修改该 HTML 字符串 但它不起作用 我究竟做错了什么 document ready function body on click button function va
  • 将激活上下文 API 与不同位置的许多 dll 一起使用

    我在位置 A 运行的 Net 客户端中使用激活上下文 API 在 WS2008 上的位置 B 与 A 完全不同的位置 不是同一台计算机上的同级 后代等 加载 COM 组件 无需注册通过在 ACTCTX 中传递位置 B 它工作正常 但是 我现
  • 主线程执行完成后,Spring Batch 线程不返回

    我是春季批次的新手 我已经通过使用多个线程从 spring 创建并成功执行了作业 它工作得很好 除了程序执行完成时 程序流不会结束 停止 即 即使主方法的最后一条语句被执行 程序也不会退出 我不确定它是否继续等待线程完成或什么 有人可以就此
  • 不使用 Excel 写入 Excel 电子表格中的某些单元格?

    我想在未安装 Excel 的服务器上写入 Excel 电子表格 所以Excel自动化是不可能的 我还需要写信给certain使用 NET 的单元 这可能吗 如何实现 ODBC 驱动程序可用于在某些工作表单元格插入数据吗 无需使用昂贵的第三方
  • Assert.That 与 Assert.True

    更喜欢什么 Assert That obj Foo Is EqualTo true or Assert True obj Foo 对我来说 这两种资产是等价的 应该优先选择哪一种 在这种特殊情况下 没有区别 您将看到大致相同详细程度的输出
  • IntelliJ IDEA 中的“变量从未分配”警告只能“部分”抑制

    Java EE IntelliJ Idea 2016 3 我编写了一个类并声明了一个私有字段 Inject注解 我已经通过添加成功地从 检查结果 窗口中删除了 未使用的声明 通知javax inject Inject to 设置 gt 编辑
  • grunt-contrib-connect 中间件 CORS 解决方案,具有 keepalive true

    对于我的本地开发系统 我尝试使用 grunt contrib connect 为前端资产提供服务 我需要一个在 Firefox 中使用字体的跨域解决方案 服务器运行得很好 但我似乎无法设置标头 我正在使用 grunt contrib con
  • 单个元素中的多个文本节点?

    有人可以帮我看一下下面的屏幕截图并解释以下内容 到底是怎么回事 我如何以编程方式检测它 我如何以编程方式修复 摆脱它 我相信发生的事情是我在一个单一的文本节点中有多个文本节点preelement 我感觉很多年前我在MDN上读到这样的事情是可
  • android:dither="true" 不抖动,出了什么问题?

    我一直在尝试让 android 抖动活动的背景图像 到目前为止没有成功 我不知道出了什么问题 这就是我所做的 我的活动布局的根元素是 LinearLayout
  • 为什么自定义类型接受 Python 中的临时属性(而内置类型不接受)?

    我想知道为什么人们能够为自定义类型的实例创建一个新属性 新 意味着 先前未在类主体中定义 但无法为内置类型执行相同的操作在类型上 比如object本身 代码示例 gt gt gt class SomeClass object pass gt
  • Python导入模块错误

    我在项目中导入模块时遇到问题 我正在创建测试 但无法从测试文件导入我的 main 来测试应用程序的一个端点teste ex py 这是我的项目结构 backend api api init py main py testes init py
  • 如何在django模板中使用生成器方法?

    我想在 django 模板中使用 python 生成器 可以吗 例如 我有模型 它包含生成器对象 如下所示 class TestMe models Model property def gen self yield 1 yield 2 上下
  • Pycharm不显示数据库表

    更新PyCharm 版本2017 1 后 PyCharm不显示sqlite3数据库表不再存在 我已经测试了连接并且可以正常工作 In sqlite客户端我可以列出所有表并进行查询 其他人也遇到这个问题吗 在这种情况下无论如何都能解决吗 我使
  • 为 Clojure 协议提供多种实现

    我有一个公开常见数据相关函数的命名空间 get images insert user 然后 我有两个具有相同功能并以不同方式实现它们的数据库后端 他们按原样实现接口 每个后端都包含在一个命名空间中 我似乎无法找到如何完成此任务的良好解决方案
  • Java 项目中服务器和客户端包的共享资源

    我有一个 Java 项目 其中包含服务器包和客户端包 另外我还有一个图书馆包 我使用 eclipse 并将所有内容放入一个 Java 项目中 每个部分服务器 客户端和库都位于单独的包中 问题是当我导出时 所有内容都会添加到 Jar 文件中
  • 如何在 Azure Key Vault 中序列化和反序列化 PFX 证书?

    我有一堆字符串和 pfx 证书 我想将它们存储在 Azure Key Vault 中 只有允许的用户 应用程序才能获取它们 将字符串存储为 Secret 并不难 但是如何以可以检索它并反序列化为证书的方式序列化证书 X509证书2 http
  • Pandas:连接数据帧并保留重复索引

    我有两个数据框 我想将它们按列 axis 1 与内部联接连接起来 其中一个数据帧有一些重复的索引 但行不重复 我不想丢失其中的数据 df1 pd DataFrame a 1 b 2 a 1 b 3 a 2 b 4 columns a b s
  • Laravel - 计算目录的总大小?

    我试图获取 Laravel 中 directory 的总大小 到目前为止我只能使用 size 函数获取单个文件的大小 好像没有这方面的例子或者文档 任何对此的意见将不胜感激 谢谢 我认为你不能 Laravel 5 用途飞行系统 http f
  • 如何将负数转换为正数?

    如何在Python中将负数转换为正数 并保持积极的态度 gt gt gt n 42 gt gt gt n if you know n is negative 42 gt gt gt abs n for any n 42 不要忘记检查docs
  • 如何将枚举类型变量转换为字符串?

    如何使 printf 显示枚举类型变量的值 例如 typedef enum Linux Apple Windows OS type OS type myOS Linux 我需要的是类似的东西 printenum OS type My OS