Re: vscanf and vprintf




Eric Sosman <esosman@xxxxxxxxxxxxxxxxxxx> wrote in message
news:OtadnTvBhbRr7MLYnZ2dnUVZ_sudnZ2d@xxxxxxxxxxxxxx
Bill Reid wrote:
Kavya <Lerner84@xxxxxxxxx> wrote in message
news:1163859680.389786.170000@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

What is the basic purpose of vscanf and vprintf? Can someone explain
with small example?

They take a pointer to a list of arguments rather than the arguments
themselves. The purpose, if you need it, is to allow you to create an
argument list based on some interactive need, then pass it to the
"v"-printf and -scanf functions.

The first sentence isn't quite right, and the second is
simply wrong.

Yeah, and worse, pretty misleading...who wrote that, anyway?

The vxxxxx() functions differ from their plain xxxxx()
brethren in one way: Instead of taking a variable number of
arguments they take a fixed number of arguments, one of which
is a va_list.

In one sense, they move the "variadic" list processing out of the
printf or scanf functions into the calling function where it can be
used for several purposes as you note below...

This va_list object allows the vxxxxx() function
to access its caller's variable arguments. However, it's not
illuminating to refer to a va_list as "a pointer to a list of
arguments;" a va_list is some kind of compiler magic that may
not involve pointers at all.

Whoops, FAQ update needed?

comp.lang.c FAQ list · Question 15.5
Q: How can I write a function that takes a format string and a variable
number of arguments, like printf, and passes them to printf to do most
of the work?

A: Use vprintf, vfprintf, or vsprintf. These routines are like their
counterparts printf, fprintf, and sprintf, except that instead of a
variable-length argument list, they accept a single va_list pointer.

---end of FAQ excerpt

And update just about every "popular" piece of documentation on the
topic...for example, from my development package non-documentation:

The v...printf functions are known as alternate entry points
for the ...printf functions. They behave exactly like their ...printf
counterparts, but they accept a pointer to a list of arguments
instead of an argument list.

---end of non-documentation excerpt

Of course, in all cases, the argument is clearly not declared as a
pointer, so this confutzion probably arises from the way that va_arg
processes the list, or something like that...

C has no way to "create an argument list" other than by
writing a function call in the source code. The call itself
is not in any sense "variable:" if you provide a string and
three int's when you write the call, that call will always
produce an argument list consisting of a string and three
int's. Nothing less, nothing more, and nothing else. Some
systems provide extra magic to allow fancier things, but these
incantations are "C with extras," not C.

Yes.

So, what use are the vxxxxx() functions? They're handy when
you want to write a function that behaves very much like one
of the ordinary xxxxx() functions, but does something a little
bit special. For example, you might want a function that is
"just like" printf() but sends its output to a logging stream
as well as to stdout.

Yeah, the typical "professional" uses I've seen usually are handling
some type of multiple formatting and output of error conditions...

The signature should be

int doubleprint(const char *format, ...);

like printf(), but how will you actually write the function?
Do you need to write what amounts to a complete printf() format
interpreter just to implement your special logger?

vprintf() and vfprintf() to the rescue. You write something
like

int doubleprint(const char *format, ...) {
int result;
va_list ap;

/* print to stdout: */
va_start(ap, format);
vprintf(format, ap);
va_end(ap);

/* ... and now to the log: */
va_start(ap, format);
result = vfprintf(logstream, format, ap);
va_end(ap);

return result;
}

(I say "something like" because it's not entirely clear what
value to return if you get an I/O error writing to one stream
while output to the other succeeds -- but that's a separate
issue.) There is no way doubleprint() can pass its own "..."
arguments to printf() or fprintf(), but it *can* latch onto
them with a va_list and pass *that* instead.

Other likely uses: Adding time stamps or similar decorations
to output lines, "printing" to a buffer that will then be handed
to some service C's I/O doesn't support well (GUI dialog boxes,
perhaps), and anything else where you want a capability that is
similar to but a little different from that provided by a
variable-argument function in the Standard C library.

I actually posted an OFF-TOPIC example recently, using
vsprintf(), that illustrates one "real-world" use:
> [...]

This is a perfectly typical example of using a "printf-like"
function to create output for a non-printf-able destination (and
it seems adequately topical to me; no need to apologize for using
a vxxxxx() function as it is intended).

Well, in that case, let me make it off-topic (not to mention these
functions are only "standard" in the largely unused "C99"):

void print_console_buffer(unsigned new_line) {

TextOutForm->TextOutput->Lines->Strings[printed_lines]=newline;

if(new_line) {

...

}

void print_line_buffer(void) {
unsigned char_idx=0;

while(char_idx<LINEMAX) {
if(next_char==console_width) {
newline[next_char]=p_line_buffer[char_idx];
newline[next_char+1]=NUL;
next_char=0;
print_console_buffer(NEWLINE);
}

else if(p_line_buffer[char_idx]=='\n') {

...

}

int gui_printf(char *format,...) {
int print_length;

p_line_buffer[0]=NUL;
va_list ap;

va_start(ap,format);
vsprintf(p_line_buffer,format,ap);
va_end(ap);

print_length=(int)strlen(p_line_buffer);

print_line_buffer();

return print_length;
}

---
William Ernest Reid



.



Relevant Pages

  • Re: Whats the use of %p
    ... The argument shall be a pointer to void. ... Thanks for the info Keith! ... What is/are the useof %p in printf in a situation where ... Presumably an implementation will display a pointer in whatever format ...
    (comp.lang.c)
  • Re: allocating m bytes dynamically
    ... since conversion to and from a void pointer is ... Even attempting to print the variable with printf is undefined ... Print a void * in an implementation-defined format. ... This specification is a little generic (implementation-defined format). ...
    (comp.lang.c)
  • Re: Whats the use of %p
    ... The argument shall be a pointer to void. ... What is/are the useof %p in printf in a situation where ... knowing what the %p format does on your system, ...
    (comp.lang.c)
  • Re: allocating m bytes dynamically
    ... since conversion to and from a void pointer is ... Even attempting to print the variable with printf is undefined ... Print a void * in an implementation-defined format. ... to by ptr, then the assertion of undefined behavior would be reasonable. ...
    (comp.lang.c)
  • Re: ES format
    ... >> runtime format, even a runtime format that is trivially constant, not. ... You aren't allowed by Standard C to define any _external_ linkage ... In particular you certainly can define a 'static' function printf(), ... but otherwise it is part of the language and the compiler ...
    (comp.lang.fortran)