Thread: Writing to two streams: va_arg issues

  1. #1
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057

    Writing to two streams: va_arg issues

    Recently I was trying to write a function that would log the same data to two streams, stderr and a file. The function needed to support variable numbers of arguments.

    The simplest way to do it seems to be something like this:
    Code:
    #include <stdarg.h>
    
    void fprintf2(FILE *one, FILE *two, const char *format, ...) {
        va_list arg1, arg2;
    
        va_start(arg1);
        va_copy(arg1, arg2);
    
        vfprintf(one, format, arg1);
        vfprintf(one, format, arg2);
    
        va_end(arg1);
        va_end(arg2);
    }
    But the rest of the code was C89, and I was hoping not to use the C99 va_copy (or __va_copy). The only way I could see to do this was to use something like this:
    Code:
    #include <stdarg.h>
    
    void fprintf2(FILE *one, FILE *two, const char *format, ...) {
        va_list arg;
    
        va_start(arg);
        vfprintf(one, format, arg);
        va_end(arg);
    
        va_start(arg);
        vfprintf(two, format, arg);
        va_end(arg);
    }
    I wasn't sure, however, if one could call va_start twice in the same function. This thread seems to indicate that you can, if you call va_end before you call va_start for the second time: http://www.thescripts.com/forum/thread212436.html

    So apparently my va_start()-twice code is okay.

    But it seems like an awkward way to do things. Is there a better way to write something to two streams?

    I'm not just calling fprintf() twice because the calls to fprintf2() are long and complicated, and large in number. If, in the future, I decided that I needed more than one log file or something, there would be a lot of code to change.

    But the main reason that I'm not calling fprintf() twice is that my actual function looks more like this:
    Code:
    #include <stdarg.h>
    
    void log_printf(const char *format, ...) {
        va_list arg;
        FILE *log;
    
        va_start(arg);
        vprintf(format, arg);
        va_end(arg);
    
        if((log = fopen(LOG_FILE, "a"))) {
            va_start(arg);
            vfprintf(log, format, arg);
            va_end(arg);
    
            fclose(log);
        }
    }
    Opening the log file every time I needed to write something to the log would be excessive; but this is what I would have to do if I didn't have a va_args function that could write to two streams.

    So I guess my question is, is that type of code really okay? Even if it is, it seems awkward. If anyone can think of a better way to do this, their input would be appreciated.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Why not vs(n)printf the string just once, then fputs() that to both files?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Yes, that would probably work . . . Thanks.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Writing encrypted value to file.
    By mkthnx001 in forum C++ Programming
    Replies: 13
    Last Post: 05-25-2009, 12:42 PM
  2. Optimize file writing
    By Opariti in forum Windows Programming
    Replies: 7
    Last Post: 10-23-2008, 01:32 PM
  3. Code writing issues..
    By jaybo684 in forum C++ Programming
    Replies: 9
    Last Post: 07-31-2005, 07:51 PM
  4. Memmory Issues and Threads
    By ddod in forum Windows Programming
    Replies: 2
    Last Post: 08-13-2004, 10:30 AM
  5. Multi-platform support issues.
    By OOPboredom in forum C Programming
    Replies: 2
    Last Post: 04-27-2004, 06:41 PM