Tob*_*ull 1 c variadic-functions
如果想在C中编写一个函数,将一个变量参数列表传递给printf一个必须使用该vprintf版本的函数.如何为自定义函数实现此机制?
换句话说,如何是什么套的精髓vprintf除了printf在符合标准的C语言实现?
如果你想编写一个va_list以参数形式作为参数的vprintf函数,那么你就是这样做的.您可以以正常方式从va_listwith va_arg中提取参数.
不要打电话va_start或va_end上va_list:这是调用者的责任.由于您无法va_list以正常方式重新启动,如果您需要多次扫描,您将需要va_copy它.
这是一个简单的例子,仅用于说明(即它并不意味着是最好的实现).
这两个函数只是使用提供的分隔符字符串连接一堆字符串.第一个是"v"版本(如vsprintf),它实现了逻辑.第二个是varargs版本,它打包va_list并将其传递给实现.
内部函数遍历参数两次; 第一次添加字符串的大小.这两个函数都返回一个新的malloc字符串,该字符串需要被调用者释放.
参数列表必须以a结尾NULL.
char* vjoin(const char* delim, va_list ap) {
va_list aq;
va_copy(aq, ap);
size_t dlen = strlen(delim);
/* First pass. Use the copied va_list */
size_t needed = 1; /* NUL terminator */
const char* s = va_arg(aq, const char*);
if (s) {
needed += strlen(s);
while ((s = va_arg(aq, const char*)))
needed += dlen + strlen(s);
}
va_end(aq);
/* Second pass. Use the original va_list */
char* rv = malloc(needed);
size_t offset = 0;
*rv = 0;
s = va_arg(ap, const char*);
if (s) {
strcpy(rv, s);
offset = strlen(s);
while ((s = va_arg(ap, const char*))) {
strcpy(rv + offset, delim);
strcpy(rv + offset + dlen, s);
offset += dlen + strlen(s);
}
}
return rv;
}
char* join(const char* delim, ...) {
va_list ap;
va_start(ap, delim);
char* rv = vjoin(delim, ap);
va_end(ap);
return rv;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3434 次 |
| 最近记录: |