版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41035588/article/details/83220749
模拟实现printf函数
思路:要实现printf函数,首先我们应该知道printf的功能,MSDN中是这样描述的Print formatted output to the standard output stream.即格式化输出打印标准输出流,Each of the functions returns the number of characters printed, or a negative value if an error occurs.即这些函数中的每一个都返回打印的字符数
,如果发生错误,则返回负值。所以我们要做的就是模拟实现printf函数的功能。首先为大家介绍一下stdarg宏。既然不能用printf,那么我们就借助putchar来实现,遍历过程中,如果遇到’%’,那么说明后面可能会跟上类型,如果出现’c’,说明是字符型常量,输出这个字符,地址+1,继续判断,如果出现的是’s’,说明是字符串,输出后,地址+1,继续遍历,如果是其他的如’d’‘f’,则返回的类型不同之外,其他遍历方法一致,如果都不符合,就直接输出。
stdarg宏:可变参数列表是通过宏来实现的,这些宏定义与stdarg.h头文件,它是标准库的一部分。这个头文件申明了一个类型va_list和三个宏------va_start,va_arg,va_end
。我们可以申明一个类型为va_list的变量,与这几个宏配合使用,访问参数的值。
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
void my_printf(char *str,...)
{
int i = 0;
int x = 0;
char *pstr = NULL;
va_list arg; //定义va_list类型变量arg
va_start(arg,str); //arg初始化,将arg指向第一个可选参数
assert(str); //保证str不为空
while (*str)
{
if(*str == '%')
{
str++;
switch(*str)
{
case 's':
{
pstr = va_arg(arg,char*); //va_arg的第二个参数是你要返
//回的参数的类型,此处是char *
while(*pstr)
{
putchar(*pstr);
pstr++;
}
break;
}
case 'c':
{
x = va_arg(arg,char); //返回参数列表中的当前参数,并使a
//rg指向参数列表中的下一个参数
putchar(x);
x++;
break;
}
default:
{
putchar(*(str-1));
putchar(*str);
break;
}
}
str++;
}
else
{
putchar(*str);
str++;
}
}
va_end(arg); //把arg指针清为NULL
}
int main()
{
my_printf("%s %c%c%c\n","hello",'b','i','t');
system("pause");
return 0;
}