#define fprintf(fp,...) my_fprintf(fp, __VA_ARGS__)
int my_fprintf(FILE *fo, ...)
{
va_list ap;
va_start(ap,fo);
Minor: va_start() counts as code, and having code before declarations
within a block is not standard in C90, although it is supported as an
extension in several popular compilers and is standard in C99.
FILE *fp;
char *buffer;
buffer = va_arg(ap,char*);
fp = fopen("log","a");
//printf("%s %d",buffer,strlen(buffer));
if(fo == stdout || fo == stderr)
{
fp = fopen("log","a");
if (fp == NULL)
return(-1);
if(fwrite(buffer,sizeof(char),strlen(buffer),fp)> 0)
return(strlen(buffer));
This will only print the format string, not any converted data that it
calls for, which means the only valid invocations are with exactly two
arguments (fp and str) and you don't need variadic. If you really want
fprintf functionality, use vfprintf, or sprintf or better snprintf
(also a common extension in C90, standard in C99) plus fwrite.
From your description elsethread I thought you do want to
allow/support output to files other than stdout/err, you just don't
want the redirection to apply to those other files.
Works in gcc but doesn't work in the embedded IDE. I guess, the
embedded compiler does not support variable arguments macro. Though it
definitely supports variable argument functions.
vararg functions have been standard since C90, which is almost
universally implemented (modulo bugs), and were fairly common even
before standardization. variadic macros are new in C99, not yet widely
implemented, and were/are not common outside of C99 and gcc.
Though I am still testing.
Anyways, another option that I can think of is
#define fprintf(x,y) my_fprintf_1(x,y)
#define fprintf(x,y,z) my_fprintf_2(x,y,z)
...
and so on. A dirty way of doing this. What do you guys think ?
That can't work at all; Cpp allows only one definition for a macro.
What does work is
#define fprintf0(f,s), my_fprintf_0(f,s)
#define fprintf1(f,s,a) my_fprintf_1(f,s,a)
#define fprintf2(f,s,a,b) my_fprintf_2(f,s,a,b)
(where I count the number of variable/data args only) but this
requires changing each invocation, which you wanted to avoid.
Using an 'object-like' (nonparameterized) macro instead can work:
#undef fprintf
#define fprintf my_fprintf
void my_fprintf (FILE * f, /*restrict*/ const char * s, ...)
/* note signature EXACTLY SAME as real fprintf() */
{ blah blah blah }
and then usage as fprintf (fp, "foo", x, y, z) just expands to
my_fprintf (fp, "foo", x, y, z) and your function can do its thing.
Caveat: this is officially not supported by the standard -- overriding
any standard-library feature is not -- but it is likely to work on all
real implementations, at least as long as you do it only for source
i.e. NOT before #include'ing system or even third-party headers. And
of course it only applies to calls within code you write or modify and
compile, not within any object libraries that you call.
- formerly david.thompson1 || achar(64) || worldnet.att.net