1、可变参数
头文件 stdarg;类型 va_list;
宏 va_start 到达可变参数的起始位置。初始化va_list类型的变量,使其指向可变参数列表的头(即第1个可变参数)。例:va_start(ap, str);
宏 va_arg 获取可变参数,当遇到一个结束标志时停止处理。返回一个可变长度参数的值,并使va_list类型变量指向下一个可变参数。需使用一个类型名来确定要返回的类型和va_list指针需要移动的字节单位。例:Int a = va_arg(ap, int); char ch = va_arg(ap, int); char *p = va_arg(ap, char *)
2、itoa整型变量转为字符串型
首先提取整数的各个位,并将其转换为字符。最后需要将该字符串前面的若干个0去掉。
源代码:
1 /*
2 * FILE: p76_myprintf.c
3 * DATE: 20180108
4 * ---------------
5 * DESCRIPTION: myprintf()
6 * 可变参数函数
7 * 数字转字符串,并将字符串前的若干个0去掉
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdarg.h>
14
15 int myprintf(const char *format, ...);
16 char *itoa(int val, char *p);
17
18 int main(int argc, char *args[])
19 {
20 myprintf("the char is %c\nthe number is %d\nthe string is %s\n",
21 'a', 123, "hello world\n");
22 return 0;
23 }
24
25 /* 自定义的printf函数,这是一个可变参数的函数 */
26 int myprintf(const char *format, ...)
27 {
28 va_list ap;
29 char c;
30 int count = 0; // 累计输出字符个数
31 char ch;
32 int a;
33 char *p;
34 char buf[10];
35
36 va_start(ap, format); // 到达可变参数的起始位置
37
38 c = *format;
39 while(c != '\0')
40 {
41 if(c != '%')
42 {
43 putchar(c);
44 count++;
45 }
46 else if(c == '%')
47 {
48 format++; // 跳过字符%
49 c = *format;
50 switch(c)
51 {
52 case 'c': // 处理字符
53 ch = va_arg(ap, int); // 取参数
54 putchar(ch);
55 count++;
56 break;
57
58 case 'd': // 处理整数
59 a = va_arg(ap, int); // 取参数
60 itoa(a, buf);
61 fputs(buf, stdout);
62 count += strlen(buf);
63 break;
64 case 's': // 处理字符串
65 p = va_arg(ap, char *); // 取参数
66 fputs(p, stdout);
67 count += strlen(p);
68 break;
69 default:
70 perror("ERROR: myprintf, invalid arguments");
71 break;
72 }
73 }
74 format++; // 处理下一个字符
75 c = *format;
76 }
77 va_end(ap); // 清理
78 return count;
79 }
80
81 /* short型变量转为字符串 */
82 char *itoa(int val, char *p)
83 {
84 char *q;
85
86 if(p == NULL)
87 return NULL;
88
89 p[0] = (val / 10000) + '0';
90 val = val % 10000;
91
92 p[1] = (val / 1000) + '0';
93 val = val % 1000;
94
95 p[2] = (val / 100) + '0';
96 val = val % 100;
97
98 p[3] = (val /10) + '0';
99 val = val %10;
100
101 p[4] = val + '0';
102 p[5] = '\0';
103
104 // 将字符串前面的若干个0去掉
105 q = p;
106 while(*q!='\0' && *q=='0')
107 q++;
108 if(*q == '\0')
109 return p;
110 strcpy(p, q); // 将0后面的数字覆盖到缓冲区的首地址
111 return p;
112 }
编译运行: