Can we pass arguments of different datatypes to same variadic function at the same time?
+3
A:
sure, look at common usages of printf:
printf("Error %d: %s", errNum, errTxt);
AShelly
2010-10-04 04:36:38
Can you give some example except printf
Shweta
2010-10-04 04:41:44
@Shweta: scanf would be the other obvious one. Those (along with variants like sprintf, fscanf, etc.) are nearly the only variadic functions in really wide use.
Jerry Coffin
2010-10-04 04:47:25
+1
A:
so ross$ expand < variadic.c && cc -Wall -Wextra variadic.c
#include <stdio.h>
#include <stdarg.h>
void f(int, ...);
struct x { int a, b; } y = { 5, 6 };
int main(void) {
float q = 9.4;
f(0, 1.234, &q, "how now", 123, &y);
return 0;
}
void f(int nothing, ...) {
va_list ap;
va_start(ap, nothing);
double f = va_arg(ap, double);
float *f2 = va_arg(ap, float *);
char *s = va_arg(ap, char *);
int i = va_arg(ap, int);
struct x *sx = va_arg(ap, struct x *);
va_end(ap);
printf("%5.3f %3.1f %s %d %d/%d\n", f, *f2, s, i, sx->a, sx->b);
}
so ross$ ./a.out
1.234 9.4 how now 123 5/6
DigitalRoss
2010-10-04 05:04:15
A:
Here's a printf-free example ( old version: http://codepad.org/vnjFj7Uh )
#include <stdarg.h>
#include <stdio.h>
/* return the maximum of n values. if n < 1 returns 0 */
/* lying to the compiler is not supported in this version, eg: **
** va_max(4, 8, 8, 8, 8, 8, 8, 8, 8) **
** or **
** va_max(4, 2, 2) **
/* is a bad way to call the function (and invokes Undefined Behaviour) */
int va_max(int n, ...) {
int res;
va_list arg;
if (n < 1) return 0;
va_start(arg, n);
n--;
res = va_arg(arg, int);
while (n--) {
int cur = va_arg(arg, int);
if (cur > res) res = cur;
}
return res;
}
int main(void) {
int test6 = va_max(6, 1, 2, 3, 4, 5, 6);
int test3 = va_max(3, 56, 34, 12);
if (test6 == 6) puts("6");
if (test3 == 56) puts("56");
return 0;
}
pmg
2010-10-04 09:04:13
A:
I made a function to unpack binary data using a varadic function,it takes different types based on what you want "encoded/decoded".
You'd use it like:
uint32_t a;
uint16_t b;
uint16_t c;
uint8_t *buf = ....;
depickle(buf,"sis",&a,&b,&c);
where 's' expects an uint16_t* and decodes 2 bytes from buf
into a
as little endian, 'i' says to decode 4 bytes as little endian into 'b'
Or to e.g. decode 4 bytes as big endian into a uint32_t:
uint32_t a;
uint8_t buf[] = {0x12,0x34,0x56,0x78};
depickle(buf,"I",&a);
There's still an early version around here.
nos
2010-10-04 15:53:18