在代码调试时,我们经常需要直观地定位当前枚举变量为哪个枚举常量。通常通过打印枚举值就可以确定,但是当枚举常量表过多时,就不那么直观了。本篇记录一种C/C++枚举变量转字符串的实用技巧。
在学习C语言宏的时候,有看到 “#” 在宏(#define)中有一些特殊的用法,这里先回顾一下:
通过第一个用法,如果能够将 “#” 与枚举结合起来,似乎就能实现枚举转成字符串了。如何实现呢? 经过一次次迭代,大佬们给后辈实现了一种实用的技巧。
① 首先,将需要的枚举名放到固定的地方统一管理(signal_list.gen)。
// signal_list.gen
ENUM_OR_STRING(LED_OPEN), \
ENUM_OR_STRING(LED_CLOSE), \
ENUM_OR_STRING(MSG_TEST), \
ENUM_OR_STRING(MSG_BUTT) \
signal_list.gen用于管理使用的枚举名。
② 其次,声明枚举(signal_id.h)
// signal_id.h
/* 消息ID转枚举 */
#ifdef ENUM_OR_STRING
#undef ENUM_OR_STRING
#endif
#define ENUM_OR_STRING(x) x
typedef enum
{
#include "signal_list.gen"
} E_MSG_ID;
ENUM_OR_STRING(x)
替换成 x
。③ 最后,实现获取枚举字符串方法(signal_id.cc)
#ifdef ENUM_OR_STRING
#undef ENUM_OR_STRING
#endif
#define ENUM_OR_STRING(x) #x
const int MAX_LENGTH_MSG = 50;
const char msgIdString[][MAX_LENGTH_MSG] = {
#include "signal_list.gen"
};
const char *GetMsgName(int msgID)
{
return msgIdString[msgID];
}
ENUM_OR_STRING(x)
替换成 #x
,完成宏转字符串操作。#define LOGD(fmt, args...) printf("%d DemoSignal D: " fmt, __LINE__, ##args)
int main(int argc, char *argv[])
{
LOGD("Msg id [%d] name [%s]\n", MSG_TEST, GetMsgName(MSG_TEST));
return 0;
}
28 DemoSignal D: Msg id [2] name [MSG_TEST]
用心感悟,认真记录,写好每一篇文章,分享每一框干货。
更多文章内容包括但不限于C/C++、Linux、开发常用神器等,可进入“开源519公众号”聊天界面输入“文章目录” 或者 菜单栏选择“文章目录”查看。公众号后台聊天框输入本文标题,在线查看源码。