我想创建一个函数,它将采用不同类型的可变数量的参数。我的问题是如何解析参数类型。像调用者可以按任何顺序传递任何类型的参数(不指定格式说明符)。所以在调用函数中,我如何区分类型。
如何在函数var_argument中打印调用者传递的所有值?
假设我想在调用者传递的参数的var_argument函数内做sprintf
这是我的C代码
#include <stdio.h>
#include <stdarg.h>
void var_argument(int num,...);
int main()
{
var_argument(3,"Hello",7.87f,6);
var_argument(3,7.87f,"Hello",6);
return 0;
}
void var_argument(int num,...)
{
char str[80];
/* What code should I write to differentiate between types and to print all the values passed by the caller */
va_list list;
va_start(list,num);
/* How to do sprintf of the parameter passed to this function and store
the formatted output in the array str */
}
答案 0 :(得分:2)
这已经以某种方式完成了,例如printf()
有这样的机制。对于变量参数函数,您需要一个不属于变量参数的第一个参数,将其用作格式字符串以确定 n 位置的参数 x 的类型。
因为第一个参数是必需的,所以你必须有这样一个参数,并且将它用作变量参数中预期的指示似乎很自然。
以此为例,
#include <stdio.h>
#include <stdarg.h>
int
variable(const char *format, ...)
{
va_list args;
int count;
va_start(args, format);
count = 0;
while (*format != '\0') {
switch (*format++) {
case 's':
fprintf(stdout, "arg[%d]: %s\n", count, va_arg(args, const char *));
break;
case 'd':
fprintf(stdout, "arg[%d]: %d\n", count, va_arg(args, int));
break;
case 'f':
fprintf(stdout, "arg[%d]: %f\n", count, va_arg(args, double));
break;
}
count += 1;
}
va_end(args);
return 0;
}
int
main(void)
{
variable("sdf", "Example", 3, 3.1416);
}
当然,说明符与参数的实际类型之间的任何不匹配都将导致未定义的行为,并导致不良行为的逻辑结果。所以你必须非常小心,或者使用printf()
样式说明符并告诉编译器警告是否发生这种不匹配。
另一个解决方案就是像 glib 的一些函数那样做,传递一个类型说明符并紧接在参数之后,用最后一个值来表示参数的结束。参数&#34; 说明符&#34;可以是enum
枚举所有支持的类型,例如
#include <stdio.h>
#include <stdarg.h>
enum types {
String, Integer, Double, Float = Double, /* unless you want to store the value in a poitner
* there is normally no difference between these
*/
End
};
int
variable(enum types type, ...)
{
va_list args;
int count;
va_start(args, type);
count = 0;
while (type != End) {
switch (type) {
case String:
fprintf(stdout, "arg[%d]: %s\n", count, va_arg(args, const char *));
break;
case Integer:
fprintf(stdout, "arg[%d]: %d\n", count, va_arg(args, int));
break;
case Double:
fprintf(stdout, "arg[%d]: %f\n", count, va_arg(args, double));
break;
default:
fprintf(stderr, "unknown type specifier\n");
break;
}
type = va_arg(args, enum types);
count += 1;
}
va_end(args);
return 0;
}
int
main(void)
{
variable(String, "Example", Integer, 3, Double, 3.1416, End);
}