用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - c代码库

使用<stdarg.h>,实现My_printf

2016-06-25 作者: stopshooting举报

[c]代码库

#include "stdarg.h"

typedef enum{
	dec = 0,  //10进制
	hex,      //16进制(小写字母)
	HEX       //16进制(大写字母)
}Radix_TypeDef;

void Uart_SendByte(u8 byte)
{
    //code...
}

void Uart_SendStr(u8* str)
{
	while(*str != '\0')
	{
		Uart_SendByte(*str++);
	}
}

/**
  * @brief  整型数据转化为字符串 
  * @param  buf   存放字符串的指针
  *         digit 需要转化的整型数据 
  *         radix 进制   
  *               dec:十进制  
  *               hex:十六进制(小写字母) 
  *               HEX:十六进制(大写字母)  
  * @retval 返回字符的字节数
  */
int itoa(u8 *buf, int digit, Radix_TypeDef radix)
{
	u32 i;
	u8  temp;
	u8  flag = 0;
	int retval = 0;;	

	if(digit==0)
	{
		*buf = '0';
		retval = 1;
		return retval;
	}
	if(digit < 0)
	{
		*buf++ = '-';
		digit *= -1;
	}
	switch(radix)
	{
		case dec:
			for(i=1000000000; i>0; i/=10)
			{
				temp = digit/i;
				if(temp || flag)
				{
					flag = 1;
					*buf++ = '0' + temp;
					digit -= temp * i;

					retval++;
				}
			}
			break;
		case hex:
		case HEX:
			for(i=0x10000; i>0; i/=0x10)
			{
				temp = digit/i;
				if(temp || flag)
				{
					flag = 1;
					digit -= temp*i;
					if(temp < 10)
						*buf++ = '0' + temp;
					else
					{
						if(radix == hex)
							*buf++ = 'a' + temp - 10;
						else
							*buf++ = 'A' + temp - 10;
					}
					retval++;
				}
			}
			break;
	}
	return retval;
}

/**
  * @brief  使用类似printf的格式输出串口
  * @param  
  *         转义字符: \n 回车              \t 空三格  
  *                   %d 带符号10进制整型  %X 带符号16进制整型(大写字母)
  *                   %c 字符              %x 带符号16进制整型(小写字母)
  *                   %s  字符串
  *         支持格式:%d、%x、%X 三种转义字符支持数据前面补0或补空格。如 %9d, %09d, %9x, %09x, %9X, %09X
  * @retval 返回打印字节数
  */
u16 My_printf(const char* format, ...)
{
	u8 i;
	u8 flag;
	
	u8 buf[10];
	int  digit;	//数字
	char *s;
	char c;
	u16 retval = 0;	//返回值,返回打印字节数
	u8 num;
	
	u8 num_tk_up = 0;	//补缺数,(补空格或补0)
	va_list ap;
	va_start(ap,format);
	
	while(*format != '\0')
	{
		switch(*format)
		{
			case '%':
				//空缺补0或补空格
				if(format[1]>='0' && format[1]<='9')
				{
					//补0
					if(format[1] == '0')
					{
						if(format[2]>'0' && format[2]<='9')
						{
							flag = 1;
							format += 3;
						}
					}
					//补空格
					else
					{
						flag = 0;
						format += 2;
					}
					digit = va_arg(ap,int);
					num = 0;
					switch(*format++)
					{
						case 'd':
							num = itoa(buf, (u8)digit, dec);
							break;
						case 'x':
							num = itoa(buf, (u8)digit, hex);
							break;
						case 'X':
							num = itoa(buf, (u8)digit, HEX);
							break;
					}
					*(buf+num) = '\0';
					num_tk_up = 0;
					if(*(format - 2) -'0' > num)
					{
						num_tk_up = *(format - 2) - '0' - num;
					}
					for(i=0; i<num_tk_up; i++)
					{
						if(flag)
							Uart_SendByte('0');
						else
							Uart_SendByte(' ');
					}
					Uart_SendStr(buf);
					retval += num_tk_up + num;;				
				}
				else
				{
					num = 0;
					switch(*++format)
					{
						case 'd':
							digit = va_arg(ap,int);
							num = itoa(buf, digit, dec);
							*(buf+num) = '\0';
							Uart_SendStr(buf);
							break;
						case 'x':
							digit = va_arg(ap,int);
							num = itoa(buf, digit, hex);
							*(buf+num) = '\0';
							Uart_SendStr(buf);
							break;
						case 'X':
							digit = va_arg(ap,int);
							num = itoa(buf, digit, HEX);
							*(buf+num) = '\0';
							Uart_SendStr(buf);
							break;
						case 'c':
							c = va_arg(ap, char);
							num = 1;
							Uart_SendByte(c);
							break;
						case 's':
							s = va_arg(ap, char*);
							for(num=0; s[num]!='\0'; num++);
							Uart_SendStr((u8*)s);
							break;
					}
					format++;
					retval += num;
				}
				break;
			case '\\':
			case '\t':
			case '\n':
			case '\r':
			default:
				Uart_SendByte(*format++);
				retval++;
				break;
		}
	}
	va_end(ap);
	return retval;
}










网友评论    (发表评论)

共1 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...