代码之家  ›  专栏  ›  技术社区  ›  J.Jay

Typedef枚举到C中的字符串

  •  0
  • J.Jay  · 技术社区  · 10 年前

    我有如下错误类型定义。

    typedef enum {  Connection_Error
        , Parity_Error
        , Data_Read_Error 
         } error_t;
    

    我有一个函数返回“error_t”。我想将枚举更改为字符串(最好不使用 开关(外壳) ).

    如。

    char str[20];
    str = function_to_convert_to_string (error_t);
    

    差不多吧。 有什么建议吗?

    1 回复  |  直到 10 年前
        1
  •  1
  •   Dai    10 年前

    C语言没有将符号名称作为字符串存储在输出二进制程序中的任何内置规定(与Java和C#不同 .ToString() 方法),所以您必须在代码中手动执行此操作-幸运的是,预处理器能够将符号转换为字符串文字(“stringfification”),这使它变得更容易。

    请注意 typedef enum { ... } name 是不必要的,避免使用 _t 作为后缀,因为它是POSIX规范保留的。

    试试这个:

    enum errorType {
        Connection_Error,
        Parity_Error,
        Data_Read_Error
    };
    
    #define ERRMSG( ARG ) \
    case ARG: \
        return "Error: " #ARG ".";
    
    char* getErrorMessage(errorType e) {
        switch(e) {
            ERRMSG( Connection_Error )
            ERRMSG( Parity_Error )
            ERRMSG( Data_Read_Error )
            default: exit(1); // or some other error handler
        }
    }
    

    请注意您如何看到枚举在代码中手动列出两次:第一次在 enum 定义,再次在 switch 块对于小型枚举,这是很好的,但如果枚举列表很大或频繁更改,则需要采用DRY方法。您可以通过在自己的文本文件中列出所有枚举来简化它,如下所示:

    ErrorTypeEnum.inc

     ENTRY( Connection_Error )
     ENTRY( Parity_Error )
     ENTRY( Data_Read_Error )
    

    错误类型枚举.h

     #define ENTRY(NAME) NAME,
     enum errorType {
     #include "ErrorTypeEnum.inc"
         _Last
     }
     #undef ENTRY
    

    这个 _Last 条目是必需的,因为后面有逗号,还提供了获取元素计数的方法,因为 _最后 将有一个等于最后一个的数值 ENTRY + 1.

    错误类型枚举.c

    char* getErrorMessage(errorType e) {
        switch(e) {
    #define ENTRY(NAME) case NAME: return "Error: " #NAME ".";
    #include "ErrorTypeEnum.inc"
            default: exit(1); // or some other error handler
    #undef
        }
    }
    

    进一步的

    您可以通过在ENTRY宏中添加其他值来扩展这一点,例如自定义人类可读错误消息(而不是使用字符串化)。这是留给读者的练习:)