Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > how does printf handle an unknown number of arguments

Reply
Thread Tools

how does printf handle an unknown number of arguments

 
 
InuY4sha
Guest
Posts: n/a
 
      02-05-2009
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?
A short example would be WOW!
Thanks list
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-05-2009
InuY4sha <(E-Mail Removed)> writes:

> I'd like a macro or something to do something like the following


The devil is often in the detail. Questions that relate to "something
like" what you need are often a problem down the line...

> 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, ...);

but this is only where the problems start! In C, you can't enquire
about the types of these as yet unknown arguments, so something must
allow your function find out. Maybe they are all the same, maybe
there is something like a format string that implies the types... As
I say, the devil is in the detail. An idea of what you really need to
do would help.

Macros, can be used to a very limited extent. Again, I don't want to
explain all the possibilities because the chances are they won't apply
in your case!

--
Ben.
 
Reply With Quote
 
 
 
 
InuY4sha
Guest
Posts: n/a
 
      02-05-2009
On 5 Feb, 16:38, Ben Bacarisse <(E-Mail Removed)> wrote:
> InuY4sha <(E-Mail Removed)> writes:
> > I'd like a macro or something to do something like the following

>
> The devil is often in the detail. Questions that relate to "something
> like" what you need are often a problem down the line...
>
> > 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, ...);
>
> but this is only where the problems start! In C, you can't enquire
> about the types of these as yet unknown arguments, so something must
> allow your function find out. Maybe they are all the same, maybe
> there is something like a format string that implies the types... As
> I say, the devil is in the detail. An idea of what you really need to
> do would help.
>
> Macros, can be used to a very limited extent. Again, I don't want to
> explain all the possibilities because the chances are they won't apply
> in your case!
>
> --
> Ben.


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...

So let's make a simple case to detail the required functionalities,
I'd like all of the arguments to be always treated as char arrays.

Btw how would I address those "void*" arguments inside the function?

Thanks for your detailed answer for now!
 
Reply With Quote
 
jameskuyper
Guest
Posts: n/a
 
      02-05-2009
InuY4sha wrote:
> On 5 Feb, 16:38, Ben Bacarisse <(E-Mail Removed)> wrote:
> > InuY4sha <(E-Mail Removed)> writes:
> > > 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.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-06-2009
InuY4sha <(E-Mail Removed)> writes:

<snip>
> 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...


I'll add to James' reply that you should read all of section 15 of the
C FAQ: http://c-faq.com/varargs/index.html

--
Ben.
 
Reply With Quote
 
baeuar@gmail.com
Guest
Posts: n/a
 
      02-06-2009
On Feb 5, 9:29*pm, InuY4sha <(E-Mail Removed)> wrote:
> On 5 Feb, 16:38, Ben Bacarisse <(E-Mail Removed)> wrote:
>
>
>
>
>
> > InuY4sha <(E-Mail Removed)> writes:
> > > I'd like a macro or something to do something like the following

>
> > The devil is often in the detail. *Questions that relate to "something
> > like" what you need are often a problem down the line...

>
> > > 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, ...);

>
> > but this is only where the problems start! *In C, you can't enquire
> > about the types of these as yet unknown arguments, so something must
> > allow your function find out. *Maybe they are all the same, maybe
> > there is something like a format string that implies the types... *As
> > I say, the devil is in the detail. *An idea of what you really need to
> > do would help.

>
> > Macros, can be used to a very limited extent. *Again, I don't want to
> > explain all the possibilities because the chances are they won't apply
> > in your case!

>
> > --
> > Ben.

>
> 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...
>
> So let's make a simple case to detail the required functionalities,
> I'd like all of the arguments to be always treated as char arrays.
>
> Btw how would I address those "void*" arguments inside the function?
>
> Thanks for your detailed answer for now! - Hide quoted text -
>
> - Show quoted text


refer to stdarg.h in ansi standard

-

 
Reply With Quote
 
Antoninus Twink
Guest
Posts: n/a
 
      02-06-2009
On 6 Feb 2009 at 6:05, Han from China wrote:
> the scruffy-beard-and-creepy-pedophile-mugshot kind of C programmer
> like many of our comp.lang.c regulars.


Ah, I see you've visited his website too then...

Superb explanation, by the way - the only thing I'd have added is a note
about the default promotions, which can be a slightly slippery point
when dealing with varargs functions.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How could the unknown number of arguments been passed to printf srdgame C Programming 5 03-06-2009 11:36 PM
Call again a variadic function (... variable number of arguments)with same arguments that its variadic wrapper moreau.steve@gmail.com C Programming 3 12-31-2008 07:13 AM
functions and arguments.length; passing unknown number of arguments oldyork90 Javascript 10 09-27-2008 03:05 AM
How to handle variable number of arguments? Lambda C++ 2 07-03-2008 01:28 PM



Advertisments