santosh said:
Yes. Duplicate your output to both stderr and to the file. You can use a
small "wrapper" function to encapsulate this functionality.
Something like this, perhaps (but see the note that follows):
#include <stdio.h>
#include <stdarg.h>
int tfprintf(FILE *fpa, FILE *fpb, const char *fmt, ...)
{
int rc = 0;
va_list ap = {0};
va_start(ap, fmt);
rc = vfprintf(fpa, fmt, ap);
va_end(ap);
if(rc >= 0)
{
va_start(ap, fmt);
rc = vfprintf(fpb, fmt, ap);
va_end(ap);
}
return rc;
}
This function's handling of the return values from the two vfprintf calls
is not particularly satisfactory, but it's hard to see how one could come
up with a solution that would be pleasing to everyone. Here's one
possibility:
int tfprintf(int *rcb, FILE *fpa, FILE *fpb, const char *fmt, ...)
(with the obvious changes within the function itself), so that the function
returns the value returned by the first vfprintf, and *rcb is populated
with the value returned by the second vfprintf.
Here's another solution:
struct tfprintf_rt_
{
int rca;
int rcb;
};
struct tfprintf_rt_ tfprintf(FILE *fpa, FILE *fpb, const char *fmt, ...)
And here's another:
#define TFPRINTF_BOTH_OK 0
#define TFPRINTF_FAIL1 1
#define TFPRINTF_FAIL2 2
#define TFPRINTF_BOTH_BAD (TFPRINTF_FAIL1 | TFPRINTF_FAIL2)
int tfprintf(struct tfprintf_rt_ *rc, FILE *fpa, FILE *fpb, const char
*fmt, ...)
with the return value giving a quick and dirty summary in bitflag form,
with the details stored in the struct for perusal if required.
But they all suck, really, don't they? It's just a matter of finding the
method that sucks *least*, whether it is one of these or some other
construction - and that's very much a personal style choice.