如何让printf显示枚举类型变量的值?例如:
typedef enum {Linux, Apple, Windows} OS_type;
OS_type myOS = Linux;
我需要的是这样的东西
printenum(OS_type, "My OS is %s", myOS);
它必须显示字符串"Linux",而不是整数。
我想,首先我必须创建一个值索引的字符串数组。但我不知道这是不是最好的方式。这是完全可能的吗?
发布于 2011-02-24 00:20:40
真的没有什么好的方法可以做到这一点。只需设置一个由枚举索引的字符串数组。
如果您进行了大量输出,则可以定义一个接受枚举参数并为您执行查找的operator<<。
发布于 2011-02-24 01:21:32
当然,最简单的解决方案是为每个执行字符串转换的枚举编写一个函数:
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语言。
发布于 2011-02-24 00:19:19
这是预处理器模块
#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(OsType)
{
DECL_ENUM_ELEMENT(WINBLOWS),
DECL_ENUM_ELEMENT(HACKINTOSH),
} END_ENUM(OsType)
调用使用
getStringOsType(WINBLOWS);
摘自here。多酷啊?:)
https://stackoverflow.com/questions/5093460
复制相似问题