您的位置:首页 > 其它

vsprintf

2015-08-12 16:57 337 查看
int vsprintf(char *buf, const char *fmt, va_list args)
{
    int len;
    int i;
    char * str;
    char *s;
    int *ip;
 
    int flags;   
    /* flags to number() */
10  
11     int field_width;   
/* width of output field */
12     int precision;   
    /* min. # of digits for integers; max
13        
           number of chars for from string */
14     int qualifier;   
    /* 'h', 'l', or 'L' for integer fields */
15  
16     for (str=buf ; *fmt ; ++fmt)
{    //str为最终存放字符串的位置但是他随着字符串增长而增长,buf始终指向最终字符串的启始位置。fmt为格式字符串
17        
if (*fmt != '%') {                        
18        
    *str++ = *fmt;             
//如果不是%则表示这是需要原样打印的字符串,直接复制即可
19        
    continue;
20        
}
21        
   
22        
/* process flags */
23        
flags = 0;
24        
repeat:
25        
    ++fmt;   
    /* this also skips first '%' */                           
//fmt指向%的后一位
26        
    switch (*fmt) {
27        
        case '-': flags |= LEFT; goto repeat;
28        
        case '+': flags |= PLUS; goto repeat;
29        
        case ' ': flags |= SPACE; goto repeat;                        
//判断标志位,并设置flags
30        
        case '#': flags |= SPECIAL; goto repeat;
31        
        case '0': flags |= ZEROPAD; goto repeat;
32        
        }
33        
34        
/* get field width */
35        
field_width = -1;
36        
if (is_digit(*fmt))
37        
    field_width = skip_atoi(&fmt);
38        
else if (*fmt == '*') {
39        
    /* it's the next argument */
40        
    field_width = va_arg(args, int);
41        
    if (field_width < 0) {
42        
        field_width = -field_width;
43        
        flags |= LEFT;
44        
    }
45        
}
46  
47        
/* get the precision */
48        
precision = -1;
49        
if (*fmt == '.') {
50        
    ++fmt;   
51        
    if (is_digit(*fmt))
52        
        precision = skip_atoi(&fmt);
53        
    else if (*fmt == '*') {
54        
        /* it's the next argument */
55        
        precision = va_arg(args, int);
56        
    }
57        
    if (precision < 0)
58        
        precision = 0;
59        
}
60  
61        
/* get the conversion qualifier */
62        
qualifier = -1;
63        
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
64        
    qualifier = *fmt;
65        
    ++fmt;
66        
}
67  
68        
switch (*fmt) {                               
  //如果没有上面奇怪的标志位(*/./h/l/L)则fmt仍然指向%的后一位,下面判断这个标志位
69        
case 'c':
70        
    if (!(flags & LEFT))
71        
        while (--field_width > 0)
72        
           
*str++ = ' ';
73        
    *str++ = (unsigned char) va_arg(args, int);
74        
    while (--field_width > 0)
75        
        *str++ = ' ';
76        
    break;
77  
78        
case 's':
79        
    s = va_arg(args, char *);
80        
    len = strlen(s);
81        
    if (precision < 0)
82        
        precision = len;
83        
    else if (len > precision)
84        
        len = precision;
85  
86        
    if (!(flags & LEFT))
87        
        while (len < field_width--)
88        
           
*str++ = ' ';
89        
    for (i = 0; i < len; ++i)
90        
        *str++ = *s++;
91        
    while (len < field_width--)
92        
        *str++ = ' ';
93        
    break;
94  
95        
case 'o':
96        
    str = number(str, va_arg(args, unsigned long), 8,
97        
        field_width, precision, flags);
98        
    break;
99  
100        
case 'p':
101        
    if (field_width == -1) {
102        
        field_width = 8;
103        
        flags |= ZEROPAD;
104        
    }
105        
    str = number(str,
106        
        (unsigned long) va_arg(args, void *), 16,
107        
        field_width, precision, flags);
108        
    break;
109  
110        
case 'x':
111        
    flags |= SMALL;
112        
case 'X':
113        
    str = number(str, va_arg(args, unsigned long), 16,
114        
        field_width, precision, flags);
115        
    break;
116  
117        
case 'd':                                   
//如果是整型,首先设定flags,然后利用number函数将可变参数取出,并根据base(这里是10)然后转换成字符串,赋给str
118        
case 'i':
119        
    flags |= SIGN;
120        
case 'u':
121        
    str = number(str, va_arg(args, unsigned long), 10,
122        
        field_width, precision, flags);
123        
    break;
124  
125        
case 'n':
126        
    ip = va_arg(args, int *);
127        
    *ip = (str - buf);
128        
    break;
129  
130        
default:
131        
    if (*fmt != '%')//如果格式转换符不是%,则表示出错,直接打印一个%。如果是%,那么格式转换符就是%%,就由下面if(*fmt)只输出一个%
132        
        *str++ = '%';
133        
    if (*fmt)
134        
        *str++ = *fmt;//如果格式转换符不正确则输出%+不正确的格式转换符。如果是%%,则只输出一个%
135        
    else
136        
        --fmt;//如果转换格式符不是上面这些正确的,也不是空,那么直接输出,并返回到判断fmt的for语句;否则就指向末尾了,fmt后退一位,这样在for循环自动再加1进行判断时*fmt的条件就不满足,退出for循环
137        
    break;
138        
}
139     }
140     *str = '\0';//设定str字符串的最后一位为'\0'
141    return str-buf;//返回值为字符串的长度

注意:这里的vsprintf是根据fromat里面的格式化参数来判断变量的个数,这里节省了我们自己定义结束字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: