用户注册



邮箱:

密码:

用户登录


邮箱:

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

发表随想


还能输入: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、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

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

加载中,请稍后...