仿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);
}    

變參編程的關鍵就是確定所有參數在內存的長度,和每個參數的在內存的長度。

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