InuY4sha said:
InuY4sha said:
I'd like a macro or something to do something like the following ....
int a=1,b=2,c=3;
char c[4];
memcpy(c,foo("%i%i%i",a,b,c),4)
printf("%s\n",c) = 123;
I mean how do I handle an arbitrary number of arguments in C?
Ah, that is simpler. You declare (and later define) your function
with ... after the arguments you know about (and there must be at
least one of those):
int my_printf(const char *fmt, ...);
.....
The point is
1) I *need* a dbg_print function that exploit printf functionalities
(to be free to play with different behaviors in the future).. but this
could be solved with something like
#define dbg_print(x) (printf(x))
2) I'm curious about printf.. and I think that knowing the underlaying
theory before to dig into the code could save a lot of troubles...
Before standardization, the printf() function was "magic" - it did
things that no user-written C program could do, at least not in any
portable fashion. When C was first standardized, the <stdarg.h> header
was added, allowing anybody to write a routine taking a variable
number of arguments.
The function you want to implement has to parse a format string. The
easiest way to handle this would be to write a wrapper for vsprintf(),
but you wouldn't learn much about how variable arguments are handled
if you used that approach. It also needs to return a pointer to a
piece of memory which you can safely discard (at least, your example
code discards it, making it impossible to free() it if the memory were
allocated with malloc()). In order to provide a very simple example of
how to use <stdarg.h>, I'll ignore both of those features and write a
much simpler function, which takes a variable list of int arguments
and writes them to an array.
foo.h:
void foo(int, int *, ...);
foo.c:
#include <stdarg.h>
#include "foo.h"
void foo(int n, int *out, ...)
{
va_list ap;
if(!out)
return;
// out is the last field before the ... at
// the end of the function declaration.
va_start(ap, out);
while(n-- > 0)
*out++ = va_arg(ap, int);
va_end(ap);
}
A key thing to notice is that foo() must be able to figure out by some
method how many argument it expects to receive (that's what n is for),
and what types they have (in this case, its expecting exclusively
'int' arguments. The <stdarg.h> routines do not, themselves, provide
any way of determining those answers.