面试题答案
一键面试自定义错误码体系设计
- 错误码定义:定义一个枚举类型来表示自定义错误码。每个模块可以有自己独立的错误码范围,以避免冲突。
// 自定义错误码定义
typedef enum {
// 通用错误码
MYLIB_ERR_GENERIC = -1,
// 模块1错误码范围
MYLIB_ERR_MODULE1_BASE = -100,
MYLIB_ERR_MODULE1_IO_FAILURE = -101,
MYLIB_ERR_MODULE1_INVALID_ARG = -102,
// 模块2错误码范围
MYLIB_ERR_MODULE2_BASE = -200,
MYLIB_ERR_MODULE2_MEMORY_ALLOC_FAILURE = -201,
MYLIB_ERR_MODULE2_DATA_CORRUPT = -202
} mylib_errno;
- 错误信息映射:为每个错误码定义对应的错误信息字符串,方便调试和错误处理。
// 错误信息映射表
const char* mylib_strerror(mylib_errno err) {
switch (err) {
case MYLIB_ERR_GENERIC: return "Generic error";
case MYLIB_ERR_MODULE1_IO_FAILURE: return "Module1: I/O failure";
case MYLIB_ERR_MODULE1_INVALID_ARG: return "Module1: Invalid argument";
case MYLIB_ERR_MODULE2_MEMORY_ALLOC_FAILURE: return "Module2: Memory allocation failure";
case MYLIB_ERR_MODULE2_DATA_CORRUPT: return "Module2: Data corruption";
default: return "Unknown error";
}
}
与errno系统结合使用
- 设置errno:在发生错误时,除了设置自定义错误码,还可以根据错误类型设置相应的errno值。这样可以利用系统的错误处理机制。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
// 示例函数,模拟模块1的操作
mylib_errno module1_operation(int arg) {
if (arg < 0) {
errno = EINVAL; // 设置系统errno
return MYLIB_ERR_MODULE1_INVALID_ARG;
}
// 模拟I/O操作失败
if (rand() % 2) {
errno = EIO;
return MYLIB_ERR_MODULE1_IO_FAILURE;
}
return 0;
}
- 处理错误:在调用函数后,可以检查自定义错误码和errno,根据具体情况进行处理。
int main() {
mylib_errno err = module1_operation(-1);
if (err) {
printf("Custom error: %s\n", mylib_strerror(err));
printf("System error: %s\n", strerror(errno));
} else {
printf("Operation successful\n");
}
return 0;
}
在上述代码中:
- 首先定义了一个自定义的错误码枚举类型
mylib_errno
,并为每个错误码定义了相应的错误信息映射函数mylib_strerror
。 - 在
module1_operation
函数中,根据不同的错误情况设置了自定义错误码和系统errno
。 - 在
main
函数中,调用module1_operation
函数并处理返回的错误码,同时打印自定义错误信息和系统错误信息。