c - 在 C 中映射非顺序值的最佳方法

标签 c algorithm data-structures error-handling

我有一个非常人为设计的错误代码系统(几百个非顺序值,C 语言),同样人为设计的转换为人类可读的错误消息。

我正在考虑重构它,但我不确定将值映射到其对应字符串的最佳方式。有小费吗?

错误代码是唯一的,不能用来编写新的代码。

构建错误代码时,每个代码都有一个base 值,指定它属于哪个模块。警告和状态消息有偏移量:

#define SOME_MODULE_ERR_BASE    0x120000
#define OTHER_MODULE_ERR_BASE   0x130000

#define STATUS_OFFSET  1000
#define WARNING_OFFSET 2000

/* Error codes as defined as needed, sequentially from the base value */
#define SOME_MODULE_ERR_NOT_FOUND   (SOME_MODULE_ERR_BASE + 1)
#define SOME_MODULE_ERR_BAD_CRC     (SOME_MODULE_ERR_BASE + 2)
#define SOME_MODULE_STATUS_BUSY     (SOME_MODULE_ERR_BASE + STATUS_OFFSET + 1)
#define SOME_MODULE_WARNING_INCOMPLETE (SOME_MODULE_ERR_BASE + WARNING_OFFSET + 1)

#define OTHER_MODULE_ERR_BAD_CRC     (OTHER_MODULE_ERR_BASE + 1)
#define OTHER_MODULE_ERR_NOT_FOUND   (OTHER_MODULE_ERR_BASE + 2)
/*...*/

我们目前有代码来打印适当的错误字符串,但是转换过程(从错误代码到字符串)非常奇怪,甚至添加新的错误代码也是一件苦差事。我想改进我们的日志系统,但是这个愚蠢的代码妨碍了我。通过重构错误消息打印,我将能够重构日志系统。

基本上,我想要这个:

result = SomeModuleFunc();
printf("SomeModuleFunc returned %s\n", ErrToString(result));

它会打印 SOME_MODULE_ERR_NOT_FOUNDSOME_MODULE_ERR_BAD_CRCSOME_MODULE_STATUS_BUSY 等。

在我看来,最简单的方法就是构建一个指向适当字符串的巨大 switch-case 语句,但也许这只是因为我想不出一个好的数据结构来简化映射过程。

最佳答案

除非错误代码很大,或者您的资源非常有限,否则我的解决方案是只使用大量指向消息的字符指针。

const char *error_msg[] = {
    "", "", "Out of memory", "", "Out of disk space", 
    "", "", "", "Unauthorized user" ... 
};

它很简单而且有效。如果最高代码非常高(您的情况似乎如此),您可能会遇到问题。在这种情况下,使用指向指针的指针。

const char **error_msg;

void init_error() 
{
    error_msg = calloc(size, sizeof(*error_msg));
    error_msg[2] = "Out of memory";
    error_msg[4] = "Out of disk space";
    error_msg[8] = "Unauthorized user";
}

使用后一种方法,您不能在全局空间中进行初始化,因此使用一个 init 函数并在 main 的开头调用它。但是对于两者你都可以使用这个函数,只要 error_msg 是全局的。

const char *ErrToString(size_t code) 
{ 
    return error_msg[code]; 
}

当然,这种方法会浪费内存,但除非您的资源非常有限,否则这不是问题。基数 0x130000 的十进制数约为 120 万。所以如果指针是 8 个字节,这将低于 10MB,这在现代计算机上不算什么。而且它绝对比任何散列法或二进制搜索都快得多。通常,当您必须生成错误消息时,生成错误消息的性能并不是最大的问题,但如果您关心这一点,则可能值得了解一下。

优点:

  • 实现起来极其简单
  • 快速照明

缺点:

  • 浪费内存

简单往往是最好的。不要让事情复杂化。

关于c - 在 C 中映射非顺序值的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57012387/

相关文章:

c - 发送UDP包到NTP服务器并接收时间(lwip、Cortex M3、Stellaris LM3S6965评估板)

c - 在 openMP 中,如何确保线程在继续之前同步?

C Structure post increment 将结构增加 4 个字节?为什么是这样?

algorithm - 一种算法的时间复杂度级联到另一种算法?

c++ - 使用 set 对 log(N) 进行排序?

arrays - 使用给定的字典从一个字符串到达​​另一个字符串

c - 如何在已安装 OpenSSL 的 Linux 中使用 BoringSSL?

c++ - 如何在 STL 容器 C++11 中查找不同值

algorithm - 在树中搜索具有特定属性的节点并分配树的属性的有效方法

python - 查找数组中缺失的元素