实现自己的printf函数

来源:互联网 发布:unity3d transform 编辑:程序博客网 时间:2024/04/30 03:46

在嵌入式开发中,常常会通过串口打印一些信息到PC终端,这就需要实现自己的printf函数,下面介绍打印函数print的实现。
print.h

#ifndef     __PRINT_H_#define    __PRINT_H_void    print(char* fmt, ...);void    printch(char ch);void    printdec(int dec);void    printflt(double flt);void    printbin(int bin);void    printhex(int hex);void    printstr(char* str);#define console_print(ch)    putchar(ch)#endif    /*#ifndef __PRINT_H_*/

上面print函数为全功能的打印函数,可以实现类似printf的功能,printch实现单个字符的打印、printdec实现十进制格式数字的打印,printflt实现浮点数的打印,printbin实现二进制格式数字的打印,printhex实现十六进制格式数字的打印,printstr实现字符串的打印,console_print函数是串口单字符打印函数的宏定义,这里暂时用PC终端单字符打印函数putchar代替。在实际嵌入式环境下,替换成串口单字符打印函数即可。
print.c

#include <stdio.h>#include <stdarg.h>#include "print.h"int main(void){    print("print: %c\n", 'c');    print("print %d\n", 1234567);    print("print: %f\n", 1234567.1234567);    print("print: %s\n", "string test");    print("print: %b\n", 0x12345ff);    print("print: %x\n", 0xabcdef);    print("print: %%\n");    return 0;}void    print(char* fmt, ...){    double vargflt = 0;    int  vargint = 0;    char* vargpch = NULL;    char vargch = 0;    char* pfmt = NULL;    va_list vp;    va_start(vp, fmt);    pfmt = fmt;    while(*pfmt)    {        if(*pfmt == '%')        {            switch(*(++pfmt))            {                                case 'c':                    vargch = va_arg(vp, int);                     /*    va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI                        mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */                    printch(vargch);                    break;                case 'd':                case 'i':                    vargint = va_arg(vp, int);                    printdec(vargint);                    break;                case 'f':                    vargflt = va_arg(vp, double);                    /*    va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI                        mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */                    printflt(vargflt);                    break;                case 's':                    vargpch = va_arg(vp, char*);                    printstr(vargpch);                    break;                case 'b':                case 'B':                    vargint = va_arg(vp, int);                    printbin(vargint);                    break;                case 'x':                case 'X':                    vargint = va_arg(vp, int);                    printhex(vargint);                    break;                case '%':                    printch('%');                    break;                default:                    break;            }            pfmt++;        }        else        {            printch(*pfmt++);        }    }    va_end(vp);}void    printch(char ch){    console_print(ch);}void    printdec(int dec){    if(dec==0)    {        return;    }    printdec(dec/10);    printch( (char)(dec%10 + '0'));}void    printflt(double flt){    int icnt = 0;    int tmpint = 0;        tmpint = (int)flt;    printdec(tmpint);    printch('.');    flt = flt - tmpint;    tmpint = (int)(flt * 1000000);    printdec(tmpint);}void    printstr(char* str){    while(*str)    {        printch(*str++);    }}void    printbin(int bin){    if(bin == 0)    {        printstr("0b");        return;    }    printbin(bin/2);    printch( (char)(bin%2 + '0'));}void    printhex(int hex){    if(hex==0)    {        printstr("0x");        return;    }    printhex(hex/16);    if(hex < 10)    {        printch((char)(hex%16 + '0'));    }    else    {        printch((char)(hex%16 - 10 + 'a' ));    }}

编译执行结果如下:

print: cprint: 1234567print: 1234567.123456print: string testprint: 0b1001000110100010111111111print: 0xabcdefprint: %
如上所示,print函数实现了类似printf的功能。

	
				
		
原创粉丝点击