有没有更优的错误代码字符串化实现方案?
替代大型switch语句的错误码转字符串方案
针对你需要在运行时将错误码转为可读字符串的需求,这里有几个简洁易维护的实现方案,完全不需要写冗长的switch语句:
方案1:静态索引数组(最快,适合连续错误码)
如果你的错误码是连续的(比如从1开始递增),直接用数组索引对应错误码是最高效的方案,查找时间O(1):
首先在函数外定义错误码常量和对应的字符串数组:
// 定义错误码常量(根据实际需求扩展) #define ERROR_OUT_OF_MEMORY 1 #define ERROR_INVALID_CONFIG 2 #define ERROR_FILE_NOT_FOUND 3 // 数组索引与错误码一一对应,索引0留作未知错误 static const char* const error_strings[] = { "未知错误", "内存不足", "无效配置", "文件未找到" };
然后修改你的错误日志函数:
_Noreturn void InternalLogError(const char* caller, const char* file, u32 line, u32 code) { char error_message[128]; const char* code_str = error_strings[0]; // 默认未知错误 // 检查错误码是否在有效范围内 if (code < sizeof(error_strings) / sizeof(error_strings[0])) { code_str = error_strings[code]; } snprintf(error_message, 128, "\nMemphim 发生致命错误。\n" "错误码: %d - %s\n调用方: %s @ %s\n行号: %d\n", code, code_str, caller, file, line); if (CheckShellAvailability()) puts(error_message); else PushNotification("Memphim 错误报告器", error_message); exit(EXIT_FAILURE); }
方案2:X宏(最佳维护性,避免重复定义)
如果需要频繁新增或修改错误码,X宏可以让你在一处定义错误码和对应描述,自动生成常量和字符串数组,彻底避免重复劳动:
// 集中定义所有错误码、数值和描述 #define ERROR_CODES(X) \ X(ERROR_OUT_OF_MEMORY, 1, "内存不足") \ X(ERROR_INVALID_CONFIG, 2, "无效配置") \ X(ERROR_FILE_NOT_FOUND, 3, "文件未找到") \ // 新增错误直接在这里加一行即可 // 生成错误码枚举常量 #define X(name, value, desc) name = value, enum ErrorCodes { ERROR_CODES(X) ERROR_MAX // 标记最大错误码,用于范围检查 }; #undef X // 生成错误字符串数组 #define X(name, value, desc) desc, static const char* const error_strings[] = { "未知错误", ERROR_CODES(X) }; #undef X
使用方式和方案1完全一致,后续修改错误信息只需要修改ERROR_CODES块,不需要改动其他代码。
方案3:结构体映射数组(适合非连续错误码)
如果你的错误码不是连续的(比如有间隔或随机数值),可以用结构体数组存储错误码和描述的映射:
// 定义映射结构体 typedef struct { u32 code; const char* desc; } ErrorMapping; // 定义错误码和描述的映射表 static const ErrorMapping error_mappings[] = { {0x0001, "内存不足"}, {0x0003, "无效配置"}, {0x0007, "文件未找到"} // 非连续错误码直接添加即可 }; // 查找错误字符串的辅助函数 static const char* get_error_string(u32 code) { for (size_t i = 0; i < sizeof(error_mappings) / sizeof(error_mappings[0]); i++) { if (error_mappings[i].code == code) { return error_mappings[i].desc; } } return "未知错误"; }
然后在日志函数里调用get_error_string(code)即可,这种方案虽然是O(n)查找,但对于错误码数量不多的场景完全够用,灵活性最高。
内容的提问来源于stack exchange,提问作者Zenais
相关产品推荐
相关产品推荐

