随心所欲myprintf---可变参数列表的实现
(2010-10-13 15:14:06)
转载▼
标签: 可变参数列表it | 分类: 编程 |
大家可能习惯了printf家族的习惯,但是有的时候,我们可能有新的需求,C语言所带的printf家族的函数不再满足我们的需求。但强大的C语言,由stdarg.h提供了强大的字符合成和解析功能。下面,我以一个例子来给大家介绍可变参数列表的解析。
#include <stdarg.h>
#include <unistd.h>
#include <stdio.h>
#define ATTR __attribute__
static char sprint_buf[1024];
static int myprintf(char *fmt, ...) ATTR((format(printf,1,2)));
int myprintf(char *fmt, ...)
{
va_list args;
int n;
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
write(1, sprint_buf, n);
return n;
}
int
main()
{
char a[10] = "Misoralv";
char b[10] = "Klose";
int a1 = 14;
int n = myprintf("%s %s, his WorldCup goals reach %d.", a,b,a1);
printf("n=%d\n",n);
return 0;
}
简单介绍:
1. __attribute__ 为编译器提供了错误检查的功能,(format(printf,1,2)) 1= format 的位置, 2为parameters 的位置,这个后缀要加在函数声明之后。
$ cat test.c
1 extern void eprintf(const char *format, ...)
2 __attribute__((format(printf, 1, 2)));
3
4 void foo()
5 {
6 eprintf("s=%s\n", 5);
7
8 eprintf("n=%d,%d,%d\n", 1, 2);
9 }
$ cc -Wall -c test.c test.c:
In function `foo':
test.c:6: warning: format argument is not a pointer (arg 2)
test.c:8: warning: too few arguments for format
使得编译器多了一层检查,这就是__attribute__的目的。
2.va_list 用来存储可变参数表
va_start(va_list a, fmt),va_list获取fmt之后的参数列表的值, va_start的具体实现是一个宏,它的具体内容为:
#define va_start(v,l) __builtin_va_start(v,l)
// GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and will not be documented here because they may change from time to time; we do not recommend general use of these functions
同理可以理解va_end(va_list a)标识参数列表结束。
在我的函数中还有没有使用到的 va_arg,它的含义是取va_list中下一个的值。接口如下:
type va_arg ( va_list ap, type )
type: int / double/ long /...
例子:最大值
int FindMax ( int amount, ...)
{
int i,val,greater;
va_list vl; va_start(vl,amount);
greater=va_arg(vl,int);
for (i=1;i<amount;i++) {
val=va_arg(vl,int);
greater=(greater>val)?greater:val;
}
va_end(vl);
return greater;
}
在我们的函数最为重要的是
int vsprintf (char * str, const char * format, va_list arg );
format是类似"%s %s, his WorldCup goals reach %d."的输出格式。
str是按照输出格式将arg输出的字符串
返回值为int,表述输出了多少个字符。
Klose