日志模块--手动实现printf函数demo

 

       整体的实现思路就是传入一个字符串以及需要的参数(可变参数),通过对%的处理来获取我们所需要的类型,从而实现格式化字符串的操作( ("Hello %s world", "nginx") -> "Hello nginx world"),主要是细节的处理,比如有无符号类型,以及16进制转换和保留小数等问题,需要仔细思考。

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>   // 可变参
#include <stdint.h>
#include <string.h>

#include "ngx_global.h"
#include "ngx_macro.h"
#include "ngx_func.h"

static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero, uintptr_t hexadecimal, uintptr_t width);

// 用于调用主要的ngx_vslprintf()函数
u_char *ngx_slprintf(u_char *buf, u_char *last, const char *fmt, ...){
    va_list args;            // 定义可变参的变量
    u_char *p;

    va_start(args, fmt);     // 使args指向起始的参数
    p = ngx_vslprintf(buf, last, fmt, args);
    va_end(args);            // 释放args
    return p;
}

// 自定义的格式化输出
// buf:存储数据  last:最大的内存地址  fmt:可变参数开头(format)
u_char *ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args){

  u_char zero;       // 占位符号 0或者空格
  uintptr_t width, sign, hex, frac_width, scale, n;   // 需要用到的临时变量

  int64_t   i64;      // 保存%d
  uint64_t  ui64;     // 保存%ud
  u_char    *p;       // 保存%s
  double    f;        // 保存%f
  uint64_t  frac;     // 用于%.2f参数 保存保留的小数部分 %.2f 12.457 此时frac = 46

  // 处理fmt字符串
  while(*fmt && buf < last){
    if(*fmt == '%'){     // 表示该位置需要被替换

      // -----------------------初始化变量----------------------
      zero = (u_char)((*++fmt == '0') ? '0' : ' ');   // 判断%后面是否用0占位 如果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值