实现自己的printf函数

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

  1. #ifndef     __PRINT_H_  
  2. #define    __PRINT_H_  
  3.   
  4. void    print(char* fmt, ...);  
  5. void    printch(char ch);  
  6. void    printdec(int dec);  
  7. void    printflt(double flt);  
  8. void    printbin(int bin);  
  9. void    printhex(int hex);  
  10. void    printstr(char* str);  
  11.   
  12. #define console_print(ch)    putchar(ch)  
  13.   
  14. #endif    /*#ifndef __PRINT_H_*/  

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

  1. #include <stdio.h>  
  2. #include <stdarg.h>  
  3. #include "print.h"  
  4.   
  5. int main(void)  
  6. {  
  7.     print("print: %c\n"'c');  
  8.     print("print %d\n", 1234567);  
  9.     print("print: %f\n", 1234567.1234567);  
  10.     print("print: %s\n""string test");  
  11.     print("print: %b\n", 0x12345ff);  
  12.     print("print: %x\n", 0xabcdef);  
  13.     print("print: %%\n");  
  14.     return 0;  
  15. }  
  16.   
  17. void    print(char* fmt, ...)  
  18. {  
  19.     double vargflt = 0;  
  20.     int  vargint = 0;  
  21.     char* vargpch = NULL;  
  22.     char vargch = 0;  
  23.     char* pfmt = NULL;  
  24.     va_list vp;  
  25.   
  26.     va_start(vp, fmt);  
  27.     pfmt = fmt;  
  28.   
  29.     while(*pfmt)  
  30.     {  
  31.         if(*pfmt == '%')  
  32.         {  
  33.             switch(*(++pfmt))  
  34.             {  
  35.                   
  36.                 case 'c':  
  37.                     vargch = va_arg(vp, int);   
  38.                     /*    va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI 
  39.                         mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */  
  40.                     printch(vargch);  
  41.                     break;  
  42.                 case 'd':  
  43.                 case 'i':  
  44.                     vargint = va_arg(vp, int);  
  45.                     printdec(vargint);  
  46.                     break;  
  47.                 case 'f':  
  48.                     vargflt = va_arg(vp, double);  
  49.                     /*    va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI 
  50.                         mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */  
  51.                     printflt(vargflt);  
  52.                     break;  
  53.                 case 's':  
  54.                     vargpch = va_arg(vp, char*);  
  55.                     printstr(vargpch);  
  56.                     break;  
  57.                 case 'b':  
  58.                 case 'B':  
  59.                     vargint = va_arg(vp, int);  
  60.                     printbin(vargint);  
  61.                     break;  
  62.                 case 'x':  
  63.                 case 'X':  
  64.                     vargint = va_arg(vp, int);  
  65.                     printhex(vargint);  
  66.                     break;  
  67.                 case '%':  
  68.                     printch('%');  
  69.                     break;  
  70.                 default:  
  71.                     break;  
  72.             }  
  73.             pfmt++;  
  74.         }  
  75.         else  
  76.         {  
  77.             printch(*pfmt++);  
  78.         }  
  79.     }  
  80.     va_end(vp);  
  81. }  
  82.   
  83. void    printch(char ch)  
  84. {  
  85.     console_print(ch);  
  86. }  
  87.   
  88. void    printdec(int dec)  
  89. {  
  90.     if(dec==0)  
  91.     {  
  92.         return;  
  93.     }  
  94.     printdec(dec/10);  
  95.     printch( (char)(dec%10 + '0'));  
  96. }  
  97.   
  98. void    printflt(double flt)  
  99. {  
  100.     int icnt = 0;  
  101.     int tmpint = 0;  
  102.       
  103.     tmpint = (int)flt;  
  104.     printdec(tmpint);  
  105.     printch('.');  
  106.     flt = flt - tmpint;  
  107.     tmpint = (int)(flt * 1000000);  
  108.     printdec(tmpint);  
  109. }  
  110.   
  111. void    printstr(char* str)  
  112. {  
  113.     while(*str)  
  114.     {  
  115.         printch(*str++);  
  116.     }  
  117. }  
  118.   
  119. void    printbin(int bin)  
  120. {  
  121.     if(bin == 0)  
  122.     {  
  123.         printstr("0b");  
  124.         return;  
  125.     }  
  126.     printbin(bin/2);  
  127.     printch( (char)(bin%2 + '0'));  
  128. }  
  129.   
  130. void    printhex(int hex)  
  131. {  
  132.     if(hex==0)  
  133.     {  
  134.         printstr("0x");  
  135.         return;  
  136.     }  
  137.     printhex(hex/16);  
  138.     if(hex < 10)  
  139.     {  
  140.         printch((char)(hex%16 + '0'));  
  141.     }  
  142.     else  
  143.     {  
  144.         printch((char)(hex%16 - 10 + 'a' ));  
  145.     }  
  146. }  

编译执行结果如下:

  1. print: c  
  2. print: 1234567  
  3. print: 1234567.123456  
  4. print: string test  
  5. print: 0b1001000110100010111111111  
  6. print: 0xabcdef  
  7. print: %  
如上所示,print函数实现了类似printf的功能。

  1. <pre></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
posted @ 2014-11-10 15:56  SuperThinker  阅读(26)  评论(0编辑  收藏  举报  来源