基于静态库日志头文件实现自定义Logger函数的疑问
问题分析与解决方案
异常输出的原因
你遇到的异常源于Logger_UserLogOutput的实现逻辑错误:
- 宏
USER_LOG_DEBUG已经将格式化字符串拼接为"[%s:%d) debug msg",其中包含%s和%d占位符,需要被__FUNCTION__和__LINE__替换。 - 你直接用
printf("[DEBUG] %s\n", fmt)输出,相当于把带占位符的字符串原封不动打印,没有解析占位符,因此出现[DEBUG] [%s:%d) debug msg的结果。 - 同时你没有正确处理可变参数,也没有根据日志级别输出对应前缀。
正确实现方式
要实现目标格式[DEBUG] function:line : debug msg,Logger_UserLogOutput需使用可变参数处理函数(如vprintf,串口输出则替换为对应串口的可变参数打印函数),具体步骤如下:
1. 实现Logger_UserLogOutput函数
#include <stdarg.h> #include <stdio.h> void Logger_UserLogOutput(E_LoggerConsoleLogLevel level, const char *fmt, ...) { // 定义日志级别对应前缀 const char *level_prefix = NULL; switch(level) { case LOGGER_CONSOLE_LOG_LEVEL_DEBUG: level_prefix = "[DEBUG] "; break; case LOGGER_CONSOLE_LOG_LEVEL_INFO: level_prefix = "[INFO] "; break; case LOGGER_CONSOLE_LOG_LEVEL_WARN: level_prefix = "[WARN] "; break; case LOGGER_CONSOLE_LOG_LEVEL_ERROR: level_prefix = "[ERROR] "; break; default: level_prefix = "[UNKNOWN] "; break; } // 打印级别前缀 printf("%s", level_prefix); // 处理格式化字符串与可变参数 va_list args; va_start(args, fmt); vprintf(fmt, args); // 串口输出可替换为对应vprint函数(如结合vsnprintf+串口发送) va_end(args); // 补充换行(若宏定义未包含) printf("\n"); }
2. 优化宏定义(可选)
若要严格匹配[DEBUG] function:line : debug msg格式,可修改宏的格式化字符串,将原有的"[%s:%d) "调整为"%s:%d : ":
#define USER_LOG_DEBUG(fmt, ...) \ Logger_UserLogOutput(LOGGER_CONSOLE_LOG_LEVEL_DEBUG, "%s:%d : " fmt, __FUNCTION__, __LINE__ , ##__VA_ARGS__)
调用USER_LOG_DEBUG("debug msg");时,拼接后的格式化字符串会变为"%s:%d : debug msg",配合函数内的级别前缀,即可输出目标格式。
核心要点
- 必须使用
va_list、va_start、va_end搭配vprintf(或对应串口的可变参数打印函数)处理可变参数,普通printf无法直接接收宏传递的可变参数列表。 - 需根据日志级别动态生成前缀,不能硬编码
[DEBUG],否则所有日志都会显示为DEBUG级别。
内容的提问来源于stack exchange,提问作者simon
相关产品推荐
相关产品推荐

