模拟实现printf函数

时间:2023-01-19 19:23:51

在学习C语言的时候,使用最多的就是printf函数了,常常用,却没有认真的思考过printf函数是如何实现的。

查了查msdc后,有了点心得,连忙记录下来。

呈上msdn上printf函数的主要相关信息:

功能:

Print formatted output to the standard output stream.
格式化输出打印到标准输出流


函数原型:

int printf( const char *format [, argument]... );


返回值:

Each of these functions returns the number of characters printed, or a negative value if an error occurs.
每一个函数返回打印的字符数量,如果发生错误返回一个负值


参数:
format 格式

Format control 格式控制

argument 参数

Optional arguments 可选参数


介绍:

The printf function formats and prints a series of characters and values to the standard output stream, stdout. If arguments follow the format string, the format string must contain specifications that determine the output format for the arguments.
printf函数格式化打印一系列字符和数值到标准输出流。如果参数遵循格式化字符串,格式化字符串必须包含确定定参数输出格式的规范。


模拟实现printf函数个人解析:

1,通过函数原型可以看出printf函数其实是一个可变参数函数。这个是最重要的。在printf函数中只需要知道传入函数的第一个参数,就可以根据该参数在栈中的存储位置获取后面参数的位置及信息了。

2,printf函数第一个参数const cahr *format,该字符串内包含并确定了后面参数的输出格式,比如"%c","%d","%d","%x"等等。

3,printf函数返回值,就是通过该函数打印到标准输出流(屏幕)的字符数。当然,出错的话就返回一个负数(我还没有见过)。

下面自己模拟一下printf函数来感受感受。

基本思路是:利用传入的第一个参数,也就是字符串。通过对字符串的遍历,若该字符为‘%’,则对它后面的字符进行判断是否是规范化输出要求的字符(比如'c','d','s',‘f’'等等),然后利用va_arg(ap,t);获取后面参数中参数所对应的信息,并输出;若不为'%',则输出该字符。同时在上述两种情况下,都需要对所打印的字符个数进行统计(包括输出数值所对应的数字的个数)。(这里输出信息还是用printf输出模拟实现printf函数

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

int m_printf(const char *str, ...)
{
char *eos = (char *)str;
int ret = 0;

va_list ap;
va_start(ap, str);

assert(str);

while (*eos)
{
if('%' == *eos)
{
int d = 0;
char c = 0;
char *s = NULL;

eos++;

switch(*eos)
{
case 's':
s = va_arg(ap, char*);
while(*s)
{
putchar(*s);
s++;
ret++;
}
//不能用puts()->会自动换行
//不能用putchar()->会只输出首字母
break;
case 'c':
// c = va_arg(ap, char);
// printf("%c", c);
putchar(va_arg(ap, char));
ret++;
break;
case 'd':
d = va_arg(ap, int);
printf("%d", d);
while(d)
{
ret++;
d /= 10;
}
break;
case '\0':
putchar('\0');
default :
;
break;
}
}
else
{
putchar(*eos);
ret++;
}

eos++;
}

va_end(ap);

return (ret);
}

int main()
{
char str1[] = "Hello";
char str2[] = "bit";
int num = 200;

int ret1 = m_printf("第%d行 : %s %c%c%c\n", 100, "hello",'b','i','t');
int ret2 = m_printf("第%d行 : %s %s\n", num, str1, str2);
//求解:中文为什么能以%c格式打印出来,而不是%s

//m_printf(NULL);
//试验:当传入空指针时。

m_printf("ret1 = %d\n",ret1);
m_printf("ret2 = %d\n",ret2);

return 0;
}


代码写的比较麻烦:各位如果有更好的办法,请不吝赐教。 模拟实现printf函数