C:标准日志函数

本文介绍了如何在C++中使用vprintf函数进行日志格式控制,以及如何在log_event函数中结合va_list和va_start/va_end来定制输出格式。作者还提供了一个日志函数示例,展示了如何根据不同日志级别输出定制化的消息。
摘要由CSDN通过智能技术生成

C++:标准日志函数

我们写日志函数通常有以下几个要求:

  • 日志等级
  • 自定义输入内容
  • 输入内容可以进行格式控制
  • 可以使用宏定义控制的日志

有关内容已经在我上一篇写的文章中发过了,除了格式控制,已经基本实现了其他功能,这期主要来补全一下格式控制这块:

怎么进行格式控制呢?这里我使用了C语言的vprintf函数:

vprintf 函数是 C 标准库中的一个功能强大的函数,用于将格式化的输出发送到标准输出(stdout)。让我们来详细了解一下 vprintf 的用法:

  • 函数声明

    int vprintf(const char *format, va_list arg);
    
  • 描述
    vprintf 函数使用参数列表发送格式化输出到标准输出(stdout)。它的工作方式类似于 printf,但是使用由 arg 标识的可变参数列表中的元素来替换格式说明符,而不是附加的函数参数。在内部,函数从 arg 标识的列表中检索参数,就好像使用了 va_arg 一样,因此 arg 的状态可能会被调用所改变。

  • 参数

    • format:这是一个字符串,包含要写入到标准输出(stdout)的文本。它可以包含嵌入的格式标签,这些标签会被随后的附加参数中指定的值替换,并按需进行格式化。格式标签的属性包括 %[flags][width][.precision][length]specifier,具体说明如下:
      • specifier:输出的类型,例如字符、整数、浮点数等。
      • flags:标识,例如对齐方式、是否显示正号等。
      • width:输出的最小字符数。
      • .precision:小数点后的位数。
      • length:参数的长度,例如短整型、长整型等。
    • arg:一个表示可变参数列表的对象,应该由 <stdarg.h> 中定义的 va_start 宏初始化。
  • 返回值

    • 如果成功,则返回写入的字符总数,否则返回一个负数。
  • 示例
    下面的示例演示了 vprintf 函数的用法:

    #include <stdio.h>
    #include <stdarg.h>
    
    void WriteFormatted(char *format, ...) {
        va_list args;
        va_start(args, format);
        vprintf(format, args);
        va_end(args);
    }
    
    int main() {
        WriteFormatted("%d variable argument\n", 1);
        WriteFormatted("%d variable %s\n", 2, "arguments");
        return 0;
    }
    

    运行上述程序将产生以下输出:

    1 variable argument
    2 variable arguments
    

请注意,vprintf 函数通常与 va_startva_end 配套使用,而在大多数情况下,输出到控制台时直接使用 printf 函数即可。只有在需要自定义 printf 函数时,才需要使用 vprintf 函数。

下面是我的日志函数:

#include <stdio.h>
#include <stdarg.h>

#define LOG_LEVEL_INFO 0
#define LOG_LEVEL_WARNING 1
#define LOG_LEVEL_ERROR 2

void log_event(int level, const char *filename, const char *format, ...){
    time_t now = time(NULL);
    char *level_str;
    FILE *fp;
    va_list args;

    switch(level) {
        case LOG_LEVEL_INFO: {
            level_str = "INFO";
            break;
        }
        case LOG_LEVEL_WARNING: {
            level_str = "WARNING";
            break;
        }
        case LOG_LEVEL_ERROR : {
            level_str = "ERROR";
            break;
        }
        default: {
            level_str = "UNKNOWN";
            break;
        }
    }
    
    fp = fopen(filename, "a");

    if(fp == NULL) {
        perror("Open file ERROR!");
        return ;
    }

    if(fp != NULL) {
        fprintf(fp, "%s [%s]: ", ctime(&now), level_str);
        va_start(args, format);
        vfprintf(fp, format, args);
        va_end(args);
        fprintf(fp, "\n");
        fclose(fp);
    }
    return ;
}
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若亦_Royi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值