3

All,

I want to control the number of passed parameters in a va_list.

va_list args;
va_start(args, fmts);
        vfprintf(stdout, fmts, args);
va_end(args);

Is there any possibility to get the number of parameters just after a va_start?

Aymanadou
  • 1,200
  • 1
  • 14
  • 36

2 Answers2

4

Not exactly what you want, but you can use this macro to count params

#include <stdio.h>
#include <stdarg.h>

#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...) N
#define NARGS(...) NARGS_SEQ(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define fn(...) fn(NARGS(__VA_ARGS__) - 1, __VA_ARGS__)

static void (fn)(int n, const char *fmt, ...)
{
    va_list args;

    va_start(args, fmt);
    printf("%d params received\n", n);
    vprintf(fmt, args);
    va_end(args);
}

int main(void)
{
    fn("%s %d %f\n", "Hello", 7, 5.1);
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
2

You can not count them directly.

For example printf is a variable count function which uses its first parameter to count the following arguments:

printf("%s %i %d", ...);

Function printf first parses its first argument ("%s %i %d") and then estimates there are 3 more arguments.

In your case, you have to parse fmts ans extract %-specifiers then estimate other arguments. Actually each %[flags][width][.precision][length]specifier could count as an argument. read more...

masoud
  • 55,379
  • 16
  • 141
  • 208
  • Exactly, what i want to do is to make my function (like printf more secure), For instance, if we have a printf(%s%s) and we pass only one parameter we will have a probleme because the second %s does'nt match any arguments so we will find in the output bizzard caracters... – Aymanadou Mar 04 '13 at 09:46
  • You can not avoid those mistakes, `printf` itself cannot force the caller to pass arguments as same as specifiers. – masoud Mar 04 '13 at 09:49
  • For example you can write `printf("%i%i", 12);` it's wrong but possible – masoud Mar 04 '13 at 09:50
  • The best thing for the OP to do in this case would be to check the compiler documentation for possibilities to check arguments against format strings, which is possible with some sort of attributes in MSVC, C for AIX and DEC(/HP/Compaq) C. – PJTraill Aug 25 '15 at 14:42