实现自己的print

在嵌入式开发中,常常会通过串口打印一些信息到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: c  
    print: 1234567  
    print: 1234567.123456  
    print: string test  
    print: 0b1001000110100010111111111  
    print: 0xabcdef  
    print: %  


如上所示,print函数实现了类似printf的功能。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值