C语言 va_start / va_end / va_arg 自定义 printf 函数

零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门


一.前言

对 printf 函数的使用,我们并不陌生,首先我们来看看下面关于 printf 函数的几种调用方式:

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 va_start / va_end / va_arg 自定义 printf 函数
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

printf("hello world");
printf("%s","hello world");
printf("%s %s","hello world","C语言教程-猿说编程");
printf("%d",3);
printf("%d %d",3,6);
printf("%d %d %d ",1,2,3);

灵魂拷问:

  • 1.printf 函数到底参数是什么类型?
  • 2.printf 函数到底有几个参数?

二.函数不定长参数简介

关于 C 语言不定长参数使用,必然离不开三个宏:  va_start 、va_arg 、va_end 

#include <stdarg.h>
#define va_start __crt_va_start
#define va_arg   __crt_va_arg
#define va_end   __crt_va_end

1.va_start

#include <stdarg.h>//必须包含头文件
/*
*   arg_ptr 指向函数参数列表中的第一个可选参数
*   argN  是位于第一个可选参数之前的固定参数, 或者说最后一个固定参数
*/
va_start(arg_ptr, argN)

2.va_arg

#include <stdarg.h>//必须包含头文件
/*
*   返回参数列表中指针arg_ptr所指的参数, 返回类型为type.
*   并使指针arg_ptr指向参数列表中下一个参数.
*   返回的是可选参数, 不包括固定参数.
*/
va_arg(arg_ptr, type)

3.va_end

#include <stdarg.h>//必须包含头文件
/*
*   清空参数列表, 并置参数指针arg_ptr无效.
*/
va_end(arg_ptr)

三.win32 控制台版本

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 va_start / va_end / va_arg 自定义 printf 函数
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

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

void WriteFrmtd(char *format, ...)
{
   va_list args;

   va_start(args, format);
   vprintf(format, args);
   va_end(args);
}

int main ()
{
   WriteFrmtd("%d variable argument\n", 1);
   WriteFrmtd("%d variable %s\n", 2, "arguments");

   return(0);
}
/*
输出:

1 variable argument
2 variable arguments
请按任意键继续. . .
*/

四.MFC对话框版本

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 va_start / va_end / va_arg 自定义 printf 函数
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

BOOL printDebugMsgA(CHAR *format, ...)
{
	CHAR buf[1024] = { 0 };
	CHAR out[2048] = { 0 };
	time_t timep;
	struct tm p;
	time(&timep);
	localtime_s(&p, &timep);

	va_list args;
	va_start(args, format);
	vsprintf_s(buf, format, args);
	va_end(args);
	sprintf_s(out, "[%d-%d-%d %d:%d:%d ]: %s \n", 1900 + p.tm_year, 1 + p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec, buf);
	OutputDebugStringA(out);
	return TRUE;
}
BOOL printDebugMsgW(WCHAR *format, ...)
{
	WCHAR buf[2048] = { 0 };
	WCHAR out[2048] = { 0 };
	time_t timep;
	struct tm p;
	time(&timep);
	localtime_s(&p, &timep);

	va_list args;
	va_start(args, format);
	vswprintf_s(buf, 2048, format, args);
	va_end(args);
	wsprintf(out, L"[%d-%d-%d %d:%d:%d ]: %s \n", 1900 + p.tm_year, 1 + p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec, buf);
	//wsprintf(out, L"%s", buf); 
	OutputDebugStringW(out);
	return TRUE;
}



printDebugMsgA("猿说编程 %s %d %f", "xia处理", 1991, 1775.5);
printDebugMsgW(L"猿说编程 %s %d %f", L"xia处理", 1991, 1775.5);

/*
输出:
    
[2020-5-29 11:37:45 ]: 猿说编程 xia处理 1991 1775.500000 
[2020-5-29 11:37:45 ]: 猿说编程 xia处理 1991 1775.500000 
*/

五.猜你喜欢

  1. C语言 数组下标越界和内存溢出区别
  2. C语言 使用指针遍历数组
  3. C语言 指针和数组区别
  4. C语言 指针数组和数组指针区别
  5. C语言 野指针
  6. C语言 函数值传递和址传递
  7. C语言 函数不定长参数
  8. C语言 函数指针
  9. C语言 指针函数
  10. C语言 回调函数 callback
  11. C语言 #pragma once
  12. C语言 #include <> 与 #include “” 区别
  13. C语言 const 修饰函数参数
  14. C语言 const 和 define 区别
  15. C语言 #运算符
  16. C语言 ##运算符
  17. C语言 __VA_ARGS__
  18. C语言 ##__VA_ARGS__
  19. C语言 函数不定长参数 ##__VA_ARGS__经典案例
  20. C语言 va_start 宏
  21. C语言 va_end 宏
  22. C语言 va_arg 宏
  23. C语言 vprintf 函数
  24. C语言 va_start / va_end / va_arg 自定义 printf 函数

未经允许不得转载:猿说编程 » C语言 va_start / va_end / va_arg 自定义 printf 函数
喜欢(2) 打赏

评论抢沙发

评论前必须登录!

不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!!

开始学习

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏