Robert Snyder
Robert Snyder

Reputation: 2409

Formatted Logging with parameters not working

I'm writing in VC++ with VS2012 pro and trying to get my logger to output something like this

03/26/2013    Registry()+
03/26/2013    Registry::LoadDWORD("VersionNumber")+;
03/26/2013    Registry(3)-

with the following lines of code

RegistryHelper::RegistryHelper()
{
    LogWriter::WriteStart("Registry");
}
bool RegistryHelper::LoadDWORDValue(char* entry, UINT defaultValue, UINT& returnValue)
{
    LogWriter::WriteStart("Registry::LoadDWORD", entry);
    //Code to get DWORD

    LogWriter::WriteEnd("Registry::LoadDWORD", returnValue);
    return true;
}

The code I have thus far is this

void LogWriter::WriteStart(const char* log, ...)
{
    tcout << log << "(";

    va_list argptr;
    va_start(argptr, log);
    vfprintf(stderr, log, argptr);
    va_end(argptr);

    std::wcout << ")+" << EOL;
}

as a test I wrote this.

LogWriter::WriteStart("Registry", "Something", "else", "Start", "STop");
char* entry = "VersionNumber";
LogWriter::WriteStart("Registry", entry);
LogWriter::WriteStart("Registry");

but i am only getting back

2013-03-26.11:41:15 Registry()+
2013-03-26.11:41:15 Registry()+
2013-03-26.11:41:15 Registry()+

but i am expecting back

2013-03-26.11:41:15 Registry(Something, else, Start, STop)+
2013-03-26.11:41:15 Registry(VersionNumber)+
2013-03-26.11:41:15 Registry()+

With some playing around with it (mainly grabbing code from online and try a few different things) I've been able to make it say Registry(Registry)+ but is about as close as I've come. (I was using a while loop and checking for NULL) I'm somewhat new to VC++ and very new to using params (sorry i'm a C# guy). This is as far as I've gotten in about 1 hour of playing around with it. What am I doing wrong?

Upvotes: 0

Views: 97

Answers (3)

Ajay
Ajay

Reputation: 18441

You are attempting to use variable-number-of-arguments feature on top of *printf function, but you are not passing any format specifier (like %d, %s) when you are calling WriteStart.

A call should be like:

LogWriter::WriteStart("Registry %s", entry);

Also, you need not to hard-code the function name to indate from where the log is being generated. The statement:

LogWriter::WriteStart("Registry::LoadDWORD", entry);

Can easily be replaced with:

LogWriter::WriteStart(__FUNCTION__, entry); // I am ignoring the format-specifier here

__FUNCTION__ will be replaced by fully-qualified function name by the preprocessor.

Moreover, you can also craft a macro that will take care of all this:

#define WRITE_LOG(_smsg) \
   LogWriter::WriteStart(__FUNCTION__ , _smsg);

And use it:

WRITE_LOG("Your log message"); // Again, I ignore format-specifier here and in macro.

If you are using macro, and using variable-argument function with format specifier, you can use __VA_ARGS__ along with macro itself.

Upvotes: 1

paulsm4
paulsm4

Reputation: 121869

Better - just pass whatever output stream you wish to use as an argument:

void LogWriter::WriteStart(FILE *fp, const char* log, ...)
{
    fprintf (fp, "(");
    va_list argptr;
    va_start(argptr, log);
    vfprintf(fp, log, argptr);
    va_end(argptr);
    fprintf (fp, ")\n");
}

Upvotes: 0

jhole
jhole

Reputation: 4236

Try

std::cout << log << "(";

va_list argptr;
va_start(argptr, log);
vfprintf(stdout, log, argptr); // use same stream here!
va_end(argptr);

std::cout << ")+" << EOL;

Upvotes: 0

Related Questions