当前位置: 首页 > 工具软件 > LogUtils > 使用案例 >

C/C++ log工具类LogUtils

黄查猛
2023-12-01

一、前言

开发中打印一些程序 log 是一个很很很常用的需求了,怎么样打印这些 log 其实也很重要,除了必须的一些信息外,通常打印出这条 log 信息所在的 文件名方法行号 这类通用信息,也可以更好的帮助我们定位问题。并且,C 语言的 printf 为例,它并不是自己换行,每行 log 还需要我们手动添加一个 \n ,这个也是比较麻烦的,还容易漏掉。

所以,我们可以定制一个这样的 log 输出工具,输出一些通用信息(例如文件名、方法名、行号等),同时还可以添加一个统一的 log 开关,达成一次性关掉所有 log 的功能。

二、LogUtils 实例

这里以 C 语言为例,写了一个 LogUtils.h 文件,其它 C++、Android NDK 等类似语言,都可以在此基础上稍加修改即可。

LogUtils.h:

#ifndef _LOG_UTILS_H_
#define _LOG_UTILS_H_
 
#include <stdio.h>
#include <string.h>
 
#define DEBUG // log开关
 
#define __FILENAME__ (strrchr(__FILE__, '/') + 1) // 文件名
 
#ifdef DEBUG
#define LOGD(format, ...) printf("[%s][%s][%d]: " format "\n", __FILENAME__, __FUNCTION__,\
                            __LINE__, ##__VA_ARGS__)
#else
#define LOGD(format, ...)
#endif
 
#endif // _LOG_UTILS_H_

编写一个小程序测试一下:

#include <stdio.h>
#include "LogUtils.h"

int main() {
    LOGD("hello world");
    LOGD("%d", 10);
    LOGD("%s : %d", "num", 20);
    LOGD();
    return 0;
}

执行结果:

[main.cpp][main][5]: hello world
[main.cpp][main][6]: 10
[main.cpp][main][7]: num : 20
[main.cpp][main][8]: 

可以看到,输出的 log 已经是按照我们预设的那样,打印出了 文件名方法行号 这类通用信息,且实现的每行 log 自动换行。

注意:

如果需要关掉所有的 log,只需要注释掉 #define DEBUG 即可。也可以通过直接在 gcc 命令中添加 -DDEBUG 定义这个宏。

三、通用的一些宏定义解释

上面的代码中用到了一些系统提供的宏定义,这里简单的介绍一下它们的含义:

  • __FILE__ : 当前文件路径,注意这个是文件路径,如果我们只希望得到文件名,那么像我上面的示例中那样处理一下即可
  • __FUNCTION__ : 函数名,即输出这条宏命令所在的函数的名字
  • __LINE__ : 行号,即输出这条宏命令所在文件的第几行
  • __VA_ARGS__ : 可变变量,即将方法中的 "..." 替换到 __VA_ARGS__ 处,前面加上 "##" 是为了适应前面一个逗号,避免 "..." 为空时出错。

值得注意的是,宏定义都是在预编译时期就会替换到相应代码中去的。

 类似资料: