The code below compiles, runs, and gives correct results. Note, however, the commented out "Experiment" code. I want to be able to call a function which accepts a variable number of parameters, which then calls another function and passes it those parameters. How can I fix the commented-code so that it compiles and runs correctly? Is it possible to have the Experiment function be a simple one-line function as I am trying to do?

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


void WriteMessageToFile (FILE* stream, char* message, ...)
{
}


void DLOG (char* filename, char* message, ...)
{
    FILE* debugFile = fopen (filename, "a");

    if (debugFile != 0)
    {
        va_list ap; /* points to each unnamed arg in turn */
        char *p, *sval;
        int ival;
        double dval;

        va_start(ap, message); /* make ap point to 1st unnamed arg */
        for (p = message; *p; p++) 
        {
            if (*p != '%') 
            {
                fputc((int) *p, debugFile);
                continue;
            }
            switch (*++p) 
            {
                case 'd':
                    ival = va_arg(ap, int);
                    fprintf(debugFile, "%d", ival);
                    break;
                case 'f':
                    dval = va_arg(ap, double);
                    fprintf(debugFile, "%f", dval);
                    break;
                case 's':
                    for (sval = va_arg(ap, char *); *sval; sval++)
                        fputc((int) *sval, debugFile);
                    break;
                default:
                    fputc((int) *p, debugFile);
                    break;
           }
       }

       va_end(ap); /* clean up when done */

       fprintf (debugFile, "\n");
       fclose (debugFile);
    }
}

/*
void Experiment (char* filename, char* message, ...)
{
    DLOG (filename, message, ...);
}
*/

int main(int argc, char *argv[]) 
{
    char* name1 = "Bob";
    char* name2 = "Sam";
    char* name3 = "Fred";
    char* name4 = "Bill";

	
    //Experiment ("SomeFile.txt", "Hello %s %s %s %s\n", name1, name2, name3, name4);
    DLOG ("SomeFile.txt", "Hello %s %s %s %s\n", name1, name2, name3, name4);

    return 0;
}

Are you talking about a variable length argument list? If you are then google "C variable length argument list".

Are you talking about a variable length argument list? If you are then google "C variable length argument list".

Googled it before posting, as I always do. That's how I got the program that I posted to work. I had never written a variable length argument list function before. I didn't see anything that addressed exactly what I was trying to do from that google search.

Is this the question you are asking?
Q: How can I write a function which takes a variable number of arguments and passes them to some other function (which takes a variable number of arguments)?

Yep, that's the question I am asking. The link says that what I am trying to do can't be done, but offers an alternative. Not sure if I can use that alternative, though since I already have DLOG written to accept the ... parameter and there are function calls to it, so I imagine those function calls would no longer work if I changed the function prototype. I'll play around with it. Thanks for the link.

There's actually not much to it and I didn't have to change DLOG prototype. I even found a nifty function called vfprintf that does all the printf stuff that I was doing before, so my function that actually does the writing is just one line now.

Here's my revised code:

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>




void WriteMessageToFile (FILE* file, const char* message, va_list ap)
{
    vfprintf (file, message, ap);
}


void DLOG (const char* filename, const char* message, ...)
{
    FILE* file = fopen (filename, "a");

    if (file != 0)
    {
        va_list ap;
        va_start (ap, message);
        WriteMessageToFile (file, message, ap);
        fclose (file);
        va_end (ap);
    }
}


void Experiment (FILE* file, int a, int b, const char* message, ...)
// a and b are just arguments to prove I don't need to use the exact same parameters
{
    if (a < b)
        return; // trivial use of a and b to test whether I can use other parameters

    va_list ap;
    va_start (ap, message);
    WriteMessageToFile (file, message, ap);
    va_end (ap);
}


int main(int argc, char *argv[]) 
{
    FILE* file;
    char* name1 = "Tom";
    char* name2 = "Al";
    char* name3 = "Tim";
    char* name4 = "Steve";
    char* name5 = "Bart";
	
    DLOG ("SomeFile.txt", "Hello %s %s %s %s\n", name1, name2, name3, name4);
    file = fopen ("SomeFile.txt", "a");

    if (!file)
        exit (1);

    Experiment (file, 1, 2, "Hello %s %s %s %s\n", name4, name3, name2, name1);
    Experiment (file, 2, 1, "Hello %s %s %s %s\n", name4, name3, name2, name1);

    Experiment (stdout, 1, 2, "Hello %s %s %s\n", name1, name3, name2);
    Experiment (stdout, 2, 1, "Hello %s %s\n", name1, name2);
    Experiment (stdout, 2, 1, "Hello %s %s %s\n", name5, name4, name3);

    fclose (file);
    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.