Q:

How do I access a specific argument without knowing it's type [variable arguments] in C?

Okay, so I am writing a log service that writes some data to some file (let's say the file's name is log).
The type of data that I want to write varies, it might be int or string or something else.
So far this is how my function looks:
void write_log(FILE * fp, char * event, ...)
{
    va_list list;
    va_start(list, event);
    // Cannot use va_arg(list, type_of_var) here!!!
}

The way I call the function might vary depending on my data:
write_log(fp, "Memory size :", mem_size);

Or
write_log(fp, "Username :", username);

I have no idea if the 3rd argument is going to be a string or an int or something else.
I could have used va_arg(list, type_of_var) but since my data's type varies arbitrarily I cannot use it.
Any idea how can I access the 3rd argument of the function without knowing it's type?

A:

There is no portable standard way to know what the types are. 
The first solution that comes to mind is to use the already well-known C idiom of having to pass a format string (e.g. printf, scanf).
void write_log(FILE * fp, char * event, const char* fmt, ...)
{
    va_list list;
    va_start(list, event);

    // process fmt and act accordingly
}

If it's going to be only one extra parameter then you can pass an enum:
enum type {
   integer,
   pointer,
   floating
};

void write_log(FILE * fp, char * event, enum type t, ...)
{
    switch(t)
    {
    case integer: // do stuff with integer
    case pointer: // do stuff with pointer
    }
}

If you have access to C11's _Generic capabilities, as most modern compilers do, you can have something of the sort:
void write_logi(FILE * fp, char * event, int);
void write_logf(FILE * fp, char * event, float);
void write_logfoo(FILE * fp, char * event, struct foo);

#define write_log(file, event, arg) _Generic((arg), \
    int: write_logi,                                \
    float: write_logf,                              \
    struct foo: write_logfoo                        \
)(file, event, arg)

Then you can call as:
write_log(fp, event, i/*int*/);
write_log(fp, event, f/*float*/);

and the appropriate function will be selected. 

