printf 函数中处理参数的核心函数

来源:互联网 发布:域名dns服务器设置 编辑:程序博客网 时间:2024/06/05 09:02

/*
* =====================================================================================
*
*       Filename:  num.c
*
*    Description:  printf 函数中处理参数的核心函数
*
*        Version:  1.0
*        Created:  2010年12月13日 18时57分52秒
*       Revision:  none
*       Compiler:  gcc
*
*         Author:  Yang Shao Kun (), cdutyangshaokun@163.com
*        Company:  College of Information Engineering of CDUT
*
* =====================================================================================
*/

static int skip_atoi(const char **s)
{
    int i, c;

    for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
        i = i*10 + c - '0';
    return i;
}

#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' */
/*将整数转换成指定进制的字符,base是进制,size是字符串的长度,type是类型选项precision是数字长度(精度)*/
static char * number(char * str, unsigned long 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' : ' ';/*如果类型要填零,则置字符变量c=‘0’,也就是‘ ’,否则等于空格字符*/
    sign = 0;
    /*符号位的处理,如果带符号,则宽度值要减一*/
    if (type & SIGN) {
        if ((signed long long)num < 0) {
            sign = '-';
            num = - (signed long long)num;
            size--;
        } else if (type & PLUS) {
            sign = '+';
            size--;
        } else if (type & SPACE) {
            sign = ' ';
            size--;
        }
    }
    /*处理特殊标记,16进制减2,8进制减一*/
    if (type & SPECIAL) {
        if (base == 16)
            size -= 2;
        else if (base == 8)
            size--;
    }
    i = 0;
    /*如果数值num为0,则零时字符串=‘0’,否则根据给定的基数将数值num转换成字符形式*/
    if (num == 0)
        tmp[i++]='0';
    else while (num != 0) {
        tmp[i++] = digits[do_div(num, base)];
    }
    /*如果数值字符个数大于精度值,则精度值扩展为数字个数值*/
    if (i > precision)
        precision = i;
    size -= precision;/*size减去用于存放的字符个数*/
    /*如果类型中没有填零和左靠齐*/
    if (!(type&(ZEROPAD+LEFT)))
        while(size-->0)/*首先在str中填写空余的宽度size值,参见程序上面对size的修改*/
            *str++ = ' ';
    if (sign)/*如果带符号位,那么则存入符号*/
        *str++ = sign;
    /*处理8进制和16进制*/
    if (type & SPECIAL) {
        if (base==8)
            *str++ = '0';
        else if (base==16) {
            *str++ = '0';
            *str++ = digits[33];//这个是x或这大写的X
        }
    }
    /*没有左对齐,在剩余的宽度中存放c字符*/
    if (!(type & LEFT))
        while (size-- > 0)
            *str++ = c;
    while (i < precision--)/*如果数字个数小于精度值,则str中放入precision个0*/
        *str++ = '0';
    while (i-- > 0)
        *str++ = tmp[i];/*转换好的数字填入str中,一共是i个*/
    while (size-- > 0)/*如果宽度值仍然大于0 ,则在剩余的宽度中放入空格*/
        *str++ = ' ';
    return str;
}

原创粉丝点击