为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++ C
蝴蝶刀刀 2019-08-06 16:00:58
如何将枚举类型变量转换为字符串?如何让printf显示枚举类型变量的值?例如:typedef enum {Linux, Apple, Windows} OS_type; OS_type myOS = Linux;而我需要的是类似的东西printenum(OS_type, "My OS is %s", myOS);必须显示字符串“Linux”,而不是整数。我想,首先我必须创建一个值索引的字符串数组。但我不知道这是否是最美妙的方式。有可能吗?
查看完整描述

3 回答

?
www说

TA贡献1775条经验 获得超8个赞

真的没有这样做的美妙方式。只需设置一个由枚举索引的字符串数组。

如果你做了很多输出,你可以定义一个运算符<<,它接受一个枚举参数并为你做查找。


查看完整回答
反对 回复 2019-08-06
?
慕森卡

TA贡献1806条经验 获得超8个赞

当然,天真的解决方案是为执行转换为字符串的每个枚举编写一个函数:

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也可以直接使用它。


查看完整回答
反对 回复 2019-08-06
?
富国沪深

TA贡献1790条经验 获得超9个赞

这是预处理器块

#ifndef GENERATE_ENUM_STRINGS    #define DECL_ENUM_ELEMENT( element ) element    #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
    #define END_ENUM( ENUM_NAME ) ENUM_NAME; \            char* GetString##ENUM_NAME(enum tag##ENUM_NAME index);#else
    #define DECL_ENUM_ELEMENT( element ) #element
    #define BEGIN_ENUM( ENUM_NAME ) char* gs_##ENUM_NAME [] =
    #define END_ENUM( ENUM_NAME ) ; char* GetString##ENUM_NAME(enum \
            tag##ENUM_NAME index){ return gs_##ENUM_NAME [index]; }#endif

枚举定义

BEGIN_ENUM(Os_type){
    DECL_ENUM_ELEMENT(winblows),
    DECL_ENUM_ELEMENT(hackintosh),}

打电话使用

GetStringOs_type(winblows);


查看完整回答
反对 回复 2019-08-06
  • 3 回答
  • 0 关注
  • 3154 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信