代码之家  ›  专栏  ›  技术社区  ›  vasia

如何以编程方式将整数映射到常量字符串?

  •  4
  • vasia  · 技术社区  · 7 年前

    我有一系列错误代码(0,1,10,11,20,30,40,…)我需要映射到相应的错误消息。由于错误代码不能方便地用作数组的索引(这将是稀疏和浪费的),我认为这可以通过宏和/或枚举来实现。

    我基本上是想创建一个函数 const char *my_strerror(int errorcode) .

    const char *err00 = "an error message";
    const char *err01 = "a different one";
    const char *err10 = "another one";
    
    const char* chatter_strerror(int error){
        switch(error){
            case 0:
                return err00;
            case 1:
                return err01;
            case 10:
                return err10;
    
            .... // 10 more cases
        }
    }
    

    当然有一种更优雅的方法可以做到这一点?

    1 回复  |  直到 7 年前
        1
  •  4
  •   ad absurdum    7 年前

    一种解决方案是创建一个包含 int 错误代码字段,以及 char * 错误消息字段。然后是一组错误消息 struct 可以使用错误代码和消息初始化。这种方法可以很容易地用新的错误消息更新代码,如果最终 结构 在错误消息数组中,用作在 .msg 字段中,遍历数组的函数将不需要知道它包含多少元素。

    这里有一个例子。这个 get_error() 函数在数组上循环,在遇到所需的错误代码时中断循环。如果达到sentinel值且未找到匹配项,则返回“无法识别的错误代码”消息。请注意,无需修改 get\u错误() 将新的错误消息添加到 error_codes[] 大堆

    #include <stdio.h>
    
    struct Errors
    {
        const char *msg;
        int code;
    };
    
    struct Errors error_codes[] = {
        { .code = 1,  .msg = "input error" },
        { .code = 5,  .msg = "format error" },
        { .code = 10, .msg = "allocation error" },
        { .msg = NULL }
    };
    
    const char * get_error(int err_code);
    
    int main(void)
    {
        printf("Error: %s\n", get_error(1));
        printf("Error: %s\n", get_error(5));
        printf("Error: %s\n", get_error(10));
        printf("Error: %s\n", get_error(-1));
    
        return 0;
    }
    
    const char * get_error(int err_code)
    {
        struct Errors *current = error_codes;
        const char *ret_msg = "Unrecognized error code";
    
        while (current->msg) {
            if (current->code == err_code) {
                    ret_msg = current->msg;
                    break;
            }
            ++current;
        }
    
        return ret_msg;
    }
    

    OP已指定 内景 错误代码,但也提到 enum s、 下面是使用 枚举 . 使用 枚举 这里增加了可读性。缺点是,当错误消息更改时,现在必须在两个地方修改代码。

    #include <stdio.h>
    
    /* Modify both the Error_Codes enum  and the following error_codes[] array
       when adding new error messages. */
    
    enum Error_Codes {
        ERRINPUT  = 1,
        ERRFORMAT = 5,
        ERRALLOC  = 10
    };
    
    struct Errors
    {
        const char *msg;
        enum Error_Codes code;
    };
    
    struct Errors error_codes[] = {
        { .code = ERRINPUT,  .msg = "input error" },
        { .code = ERRFORMAT, .msg = "format error" },
        { .code = ERRALLOC,  .msg = "allocation error" },
        { .msg = NULL }
    };
    
    const char * get_error(enum Error_Codes err_code);
    
    int main(void)
    {
        printf("Error: %s\n", get_error(ERRINPUT));
        printf("Error: %s\n", get_error(ERRFORMAT));
        printf("Error: %s\n", get_error(ERRALLOC));
        printf("Error: %s\n", get_error(-1));
    
        return 0;
    }
    
    const char * get_error(enum Error_Codes err_code)
    {
        struct Errors *current = error_codes;
        const char *ret_msg = "Unrecognized error code";
    
        while (current->msg) {
            if (current->code == err_code) {
                    ret_msg = current->msg;
                    break;
            }
            ++current;
        }
    
        return ret_msg;
    }
    

    程序输出:

    Error: input error
    Error: format error
    Error: allocation error
    Error: Unrecognized error code