猿问

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

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

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

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

而我需要的是类似的东西

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

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

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


蝴蝶刀刀
浏览 3155回答 3
3回答

www说

真的没有这样做的美妙方式。只需设置一个由枚举索引的字符串数组。如果你做了很多输出,你可以定义一个运算符<<,它接受一个枚举参数并为你做查找。

慕森卡

当然,天真的解决方案是为执行转换为字符串的每个枚举编写一个函数:enum&nbsp;OS_type&nbsp;{&nbsp;Linux,&nbsp;Apple,&nbsp;Windows&nbsp;};inline&nbsp;const&nbsp;char*&nbsp;ToString(OS_type&nbsp;v){ &nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(v) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;Linux:&nbsp;&nbsp;&nbsp;return&nbsp;"Linux"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;Apple:&nbsp;&nbsp;&nbsp;return&nbsp;"Apple"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;Windows:&nbsp;return&nbsp;"Windows"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"[Unknown&nbsp;OS_type]"; &nbsp;&nbsp;&nbsp;&nbsp;}}然而,这是一场维护灾难。借助可与C和C ++代码一起使用的Boost.Preprocessor库,您可以轻松利用预处理器并让它为您生成此功能。生成宏如下:#include <boost/preprocessor.hpp>#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem)&nbsp; &nbsp; \&nbsp; &nbsp; case elem : return BOOST_PP_STRINGIZE(elem);#define DEFINE_ENUM_WITH_STRING_CONVERSIONS(name, enumerators)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; enum name {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; BOOST_PP_SEQ_ENUM(enumerators)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; inline const char* ToString(name v)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; switch (v)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOST_PP_SEQ_FOR_EACH(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; enumerators&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\&nbsp; &nbsp; }第一个宏(以...开头X_)在第二个内部使用。第二个宏首先生成枚举,然后生成一个ToString函数,该函数接受该类型的对象并将枚举器名称作为字符串返回(此实现,出于显而易见的原因,要求枚举器映射到唯一值)。在C ++中,您可以将该ToString函数实现为operator<<重载,但我认为要求显式“&nbsp;ToString”将值转换为字符串形式更为清晰。作为用法示例,您的OS_type枚举将定义如下:DEFINE_ENUM_WITH_STRING_CONVERSIONS(OS_type,&nbsp;(Linux)(Apple)(Windows))虽然宏首先看起来像是很多工作,而OS_type外观的定义相当陌生,但请记住你必须编写一次宏,然后你可以将它用于每个枚举。您可以添加其他功能(例如,字符串形式到枚举转换)而不会有太多麻烦,它完全解决了维护问题,因为您只需在调用宏时提供一次名称。然后可以使用枚举,就好像它是正常定义的:#include&nbsp;<iostream>int&nbsp;main(){ &nbsp;&nbsp;&nbsp;&nbsp;OS_type&nbsp;t&nbsp;=&nbsp;Windows; &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;ToString(t)&nbsp;<<&nbsp;"&nbsp;"&nbsp;<<&nbsp;ToString(Apple)&nbsp;<<&nbsp;std::endl;}从帖子开始,这篇帖子中的代码片段#include <boost/preprocessor.hpp>可以编译为发布以演示解决方案。这个特殊的解决方案适用于C ++,因为它使用C ++特定的语法(例如,没有typedef enum)和函数重载,但是使用C也可以直接使用它。

富国沪深

这是预处理器块#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);
随时随地看视频慕课网APP
我要回答