美文网首页
C/C++ 枚举转字符串

C/C++ 枚举转字符串

作者: 拂去尘世尘 | 来源:发表于2022-10-23 10:34 被阅读0次

    枚举转字符串

    [TOC]

    1.开篇

      在代码调试时,我们经常需要直观地定位当前枚举变量为哪个枚举常量。通常通过打印枚举值就可以确定,但是当枚举常量表过多时,就不那么直观了。本篇记录一种C/C++枚举变量转字符串的实用技巧。

    2.实现原理

      在学习C语言宏的时候,有看到 “#” 在宏(#define)中有一些特殊的用法,这里先回顾一下:

    • #: 预处理阶段,将宏参数转化为字符串
    • ##: 预处理阶段,将两个标识符拼接成一个标识符

      通过第一个用法,如果能够将 “#” 与枚举结合起来,似乎就能实现枚举转成字符串了。如何实现呢? 经过一次次迭代,大佬们给后辈实现了一种实用的技巧。

    3.代码实现

    ① 首先,将需要的枚举名放到固定的地方统一管理(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_list.gen,将.gen文件的内容定义成枚举。

    ③ 最后,实现获取枚举字符串方法(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,完成宏转字符串操作。
    • 包含signal_list.gen,将.gen的内容定义成字符串。
    • 通过GetMsgName返回指定枚举对应的字符串。

    4.实例调试

    • 调试代码
    #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;
    }
    
    • 调试打印
    $ ./DemoSignal 
    28 DemoSignal D: Msg id [2] name [MSG_TEST]
    

    5.总结

    • 在此前面对此类需求时,通常是定义一个下标与枚举一致的数组来记录枚举字符串。此种方法在维护时,往往出现更新枚举后,数组忘记更新,又难以发现。
    • 多看一些经典的代码,从中学习实用的技巧,提升自身代码能力。

    相关文章

      网友评论

          本文标题:C/C++ 枚举转字符串

          本文链接:https://www.haomeiwen.com/subject/lvdizrtx.html