仿printf实现

多参数函数可以很好的写一个通信协议,下面试着实现printf

#include "stdio.h"
#include "stdarg.h"//变参函数包含库
#include "string.h"

char* apart_num_l(long num,char *buf,char length)
{
    int i_;
    char ag;
    long num_=num;
    char * ret_adr=buf;
    for(i_=length;i_>=0;i_--)
    {
        ag=(char)(num_%10);
        num_/=10;
        *(ret_adr+i_)=ag+'0';
    }
    *(ret_adr+length+1)='\0';
    return ret_adr;
}
char* apart_num_ul(unsigned long num,char *buf,char length)
//max  4294967295 min 0
{
    int i_;
    char ag;
    unsigned long num_=num;
    char * ret_adr=buf;
    for(i_=length;i_>=0;i_--)
    {
        ag=(char)(num_%10);
        num_/=10;
        *(ret_adr+i_)=ag+'0';
    }
    *(ret_adr+length+1)='\0';
    return ret_adr;
}
char seek_nonzere(char * ct)
{
    char i;
    for(i=0;i<9;i++)
    {
        if(*(ct+i)!='0')return i;
    }
    return 0;
}

int printff(const char* str, ...)
{
    va_list argp;          /*定义保存函数参数的个数*/  
    char s_flag=0;         //用来关闭主循环中的putchar   
    int  int_flag=0;
    char *char_pr_arg;
    char char_arg;         /*存放取出的字符串参数*/  
    int  int_arg;
    long long_arg;
    unsigned long u_long_arg;
    char buf1[50];
    char num=0;
    va_start( argp, str ); /*argp指向传入的第一个可选参数,msg是最后一个确定的参数*/ 

    char_arg=*str++;
    while(char_arg!='\0')  //主循环
    {
        if(char_arg=='%')
        { 
            char_arg=*str++ ;
            if(char_arg=='c')
                char_arg = va_arg(argp,char);   /*取出当前的参数,类型为char*/   
            if(char_arg=='s')
            {
                s_flag=1;
                char_pr_arg = va_arg( argp,char*);
                char_arg = *char_pr_arg++;
                while(char_arg!='\0')
                {   
                    putchar(char_arg);
                    char_arg = *char_pr_arg++;
                }   
            }
            if(char_arg=='d')
            {
                s_flag = 1;  
                int_arg = va_arg(argp,int)%65536;
                if(int_arg<0){putchar('-');int_arg*=-1;};
                char_pr_arg=apart_num_l(int_arg,buf1,9);
                int_flag=seek_nonzere(char_pr_arg);
                char_arg = *char_pr_arg++;

                while(char_arg!='\0')
                {   
                    if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
                    putchar(char_arg);
                    char_arg = *char_pr_arg++;
                }   

            }
            if(char_arg=='l')//max = 2147483647 min = -2147483647
            {
                s_flag = 1;  
                long_arg = va_arg(argp,long)%2147483647;
                if(long_arg<0){putchar('-');long_arg*=-1;};
                char_pr_arg=apart_num_l(long_arg,buf1,9);
                int_flag=seek_nonzere(char_pr_arg);
                char_arg = *char_pr_arg++;

                while(char_arg!='\0')
                {   
                    if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
                    putchar(char_arg);
                    char_arg = *char_pr_arg++;
                }   
            }
            if(char_arg=='u')
            {
                char_arg=*str++ ;
                if(char_arg=='l')
                {
                    s_flag = 1;  
                    u_long_arg = va_arg(argp,unsigned long);
                    char_pr_arg=apart_num_ul(u_long_arg,buf1,9);
                    int_flag=seek_nonzere(char_pr_arg);
                    char_arg = *char_pr_arg++;
                    while(char_arg!='\0')
                    {   
                        if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
                        putchar(char_arg);
                        char_arg = *char_pr_arg++;
                    }
                }
                if(char_arg=='d')
                {
                    s_flag = 1;  
                    u_long_arg = va_arg(argp,unsigned long)%65536;
                    char_pr_arg=apart_num_ul(u_long_arg,buf1,9);
                    int_flag=seek_nonzere(char_pr_arg);
                    char_arg = *char_pr_arg++;
                    while(char_arg!='\0')
                    {   
                        if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
                        putchar(char_arg);
                        char_arg = *char_pr_arg++;
                    }
                }
            }

        }
        if(!s_flag)
            putchar(char_arg);
        else s_flag=0;
        char_arg=*str++; 
    }
    va_end(argp);
    return 0;
}

void main( void )    
{
    char a[]="asdf";
    int b=123;
    printff("%d",123);
}    

变参编程的关键就是确定所有参数在内存的长度,和每个参数的在内存的长度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章