实现自己的printf函数
在嵌入式开发中,常常会通过串口打印一些信息到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: %
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>