C語言 printf函數實現__函數

來源:互聯網
上載者:User

printf()是控制台程式中最常用的函數,作用是輸入的字元、數字等資訊拼成完整的句子並且輸出到標準輸出裝置(顯示器、控制台等)。
下面是printf()定義:

int printf(const char *fmt, ...)

printf()實現部分:

int Test_printf(const char *fmt, ...){    //定義接收輸出資訊最大長度1024位元組    char printf_buf[1024];    //記錄fmt對應的地址    va_list args;    int printed;    //得到首個%對應的字元地址    Test_va_start(args, fmt);    printed = Test_vsprintf(printf_buf, fmt, args);    Test_va_end(args);    //輸出到標準輸出裝置    puts(printf_buf);    return printed;}

調用部分實現:

typedef char *  va_list; #ifdef  __cplusplus //得到參數V的地址 #define _ADDRESSOF(v)   ( &reinterpret_cast<const char &>(v) ) #else #define _ADDRESSOF(v)   ( &(v) ) #endif #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) #define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) ) #define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) #define _crt_va_end(ap)      ( ap = (va_list)0 ) #define Test_va_start _crt_va_start /* windows stdarg.h */ #define Test_va_arg _crt_va_arg #define Test_va_end _crt_va_end #define ZEROPAD    1       /* pad with zero */ #define SIGN   2       /* unsigned/signed long */ #define PLUS   4       /* show plus */ #define SPACE  8       /* space if plus */ #define LEFT   16      /* left justified */ #define SPECIAL    32      /* 0x */ #define LARGE  64      /* use 'ABCDEF' instead of 'abcdef' */ int _div(long* n,unsigned base) {     int __res;          __res = ((unsigned long) *n) % (unsigned) base;          *n = ((unsigned long) *n) / (unsigned) base;          return __res; }#define do_div(n,base) _div(&n,base)/*({ \    int __res; \    __res = ((unsigned long) n) % (unsigned) base; \    n = ((unsigned long) n) / (unsigned) base; \    __res; })*/ static inline int isdigit(int ch) {    return (ch >= '0') && (ch <= '9'); } static int skip_atoi(const char **s) {    int i = 0;    while (isdigit(**s))        i = i * 10 + *((*s)++) - '0';    return i; } static char *Test_number(char *str, long num, int base, int size, int precision,    int type) {    char c, sign, tmp[66];    const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";    int i;    if (type & LARGE)        digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";    if (type & LEFT)        type &= ~ZEROPAD;    if (base < 2 || base > 36)        return 0;    c = (type & ZEROPAD) ? '0' : ' ';    sign = 0;    if (type & SIGN) {        if (num < 0) {            sign = '-';            num = -num;            size--;        } else if (type & PLUS) {            sign = '+';            size--;        } else if (type & SPACE) {            sign = ' ';            size--;        }    }    if (type & SPECIAL) {        if (base == 16)            size -= 2;        else if (base == 8)            size--;    }    i = 0;    if (num == 0)    {        tmp[i++] = '0';    }    else    {        while (num != 0)        {            tmp[i++] = digits[do_div(num, base)];        }    }    if (i > precision)        precision = i;    size -= precision;    if (!(type & (ZEROPAD + LEFT)))        while (size-- > 0)            *str++ = ' ';    if (sign)        *str++ = sign;    if (type & SPECIAL) {        if (base == 8)            *str++ = '0';        else if (base == 16) {            *str++ = '0';            *str++ = digits[33];        }    }    if (!(type & LEFT))        while (size-- > 0)            *str++ = c;    while (i < precision--)        *str++ = '0';    while (i-- > 0)        *str++ = tmp[i];    while (size-- > 0)        *str++ = ' ';    return str; } int Test_vsprintf(char *buf, const char *fmt, va_list args) {    int len;    unsigned long num;    int i, base;    char *str;    const char *s;    int flags;      /* flags to Test_number() */    int field_width;    /* width of output field */    int precision;      /* min. # of digits for integers; max                   Test_number of chars for from string */    int qualifier;      /* 'h', 'l', or 'L' for integer fields */    for (str = buf; *fmt; ++fmt) {        if (*fmt != '%') {            *str++ = *fmt;            continue;        }        /* process flags */        flags = 0;          repeat:        ++fmt;      /* this also skips first '%' */        switch (*fmt) {        case '-':            flags |= LEFT;            goto repeat;        case '+':            flags |= PLUS;            goto repeat;        case ' ':            flags |= SPACE;            goto repeat;        case '#':            flags |= SPECIAL;            goto repeat;        case '0':            flags |= ZEROPAD;            goto repeat;        }        /* get field width */        field_width = -1;        if (isdigit(*fmt))            field_width = skip_atoi(&fmt);        else if (*fmt == '*') {            ++fmt;            /* it's the next argument */            field_width = Test_va_arg(args, int);            if (field_width < 0) {                field_width = -field_width;                flags |= LEFT;            }        }        /* get the precision */        precision = -1;        if (*fmt == '.') {            ++fmt;            if (isdigit(*fmt))                precision = skip_atoi(&fmt);            else if (*fmt == '*') {                ++fmt;                /* it's the next argument */                precision = Test_va_arg(args, int);            }            if (precision < 0)                precision = 0;        }        /* get the conversion qualifier */        qualifier = -1;        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {            qualifier = *fmt;            ++fmt;        }        /* default base */        base = 10;        switch (*fmt) {        case 'c':            if (!(flags & LEFT))                while (--field_width > 0)                    *str++ = ' ';            *str++ = (unsigned char)Test_va_arg(args, int);            while (--field_width > 0)                *str++ = ' ';            continue;        case 's':            s = Test_va_arg(args, char *);            len = strnlen(s, precision);            if (!(flags & LEFT))                while (len < field_width--)                    *str++ = ' ';            for (i = 0; i < len; ++i)                *str++ = *s++;            while (len < field_width--)                *str++ = ' ';            continue;        case 'p':            if (field_width == -1) {                field_width = 2 * sizeof(void *);                flags |= ZEROPAD;            }            str = Test_number(str,                     (unsigned long)Test_va_arg(args, void *), 16,                     field_width, precision, flags);            continue;        case 'n':            if (qualifier == 'l') {                long *ip = Test_va_arg(args, long *);                *ip = (str - buf);            } else {                int *ip = Test_va_arg(args, int *);                *ip = (str - buf);            }            continue;        case '%':            *str++ = '%';            continue;            /* integer Test_number formats - set up the flags and "break" */        case 'o':            base = 8;            break;        case 'X':            flags |= LARGE;        case 'x':            base = 16;            break;        case 'd':        case 'i':            flags |= SIGN;        case 'u':            break;        default:            *str++ = '%';            if (*fmt)                *str++ = *fmt;            else                --fmt;            continue;        }        if (qualifier == 'l')            num = Test_va_arg(args, unsigned long);        else if (qualifier == 'h') {            num = (unsigned short)Test_va_arg(args, int);            if (flags & SIGN)                num = (short)num;        } else if (flags & SIGN)            num = Test_va_arg(args, int);        else            num = Test_va_arg(args, unsigned int);        str = Test_number(str, num, base, field_width, precision, flags);    }    *str = '\0';    return str - buf; }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.