Convert __VA_ARGS__ to string

5.6k views Asked by At

I'm trying to redefine a Variadic Macro to use cout instead of printf. Here's the original code:

#define LOGE(...) PRINT_LEVEL(1, __VA_ARGS__);

  #define PRINT_LEVEL(level,...) do { \
      if (debug_components.DEBUG_COMPONENT >= level) \
          { printf("[%s]: ", levels_strings[level-1]); printf(__VA_ARGS__); printf("\n"); } \
    }while(0)

I converted this to the following to use cout instead of printf:

  #define PRINT_LEVEL(level,...) do { \
if (debug_components.DEBUG_COMPONENT >= level) \
{ std::string argString; sprintf(argString, __VA_ARGS__); std::cout << "[" << levels_strings[level-1] << "]" << argString << "\n";} \
    }while(0)

For some reason, __VA_ARGS__ works fine with printf, but NOT sprintf. It also does not work with cout. I'd like to know the correct way to convert __VA_ARGS__ to a string, or failing that, the correct way to just print it out using cout.

2

There are 2 answers

1
ShadowRanger On BEST ANSWER

sprintf takes an extra argument, the data buffer to write the output to. You can't swap out printf for sprintf without making the changes to provide that buffer. It also doesn't return a pointer to the string, so you can't assign the result to a std::string and expect it to work. If you're operating unsafely (assuming a maximum buffer length), something as simple as:

#define PRINT_LEVEL(level,...) do { \
    if (debug_components.DEBUG_COMPONENT >= level) \
    { 
        char buf[1024];
        sprintf(buf, __VA_ARGS__); std::cout << "[" << levels_strings[level-1] << "]" << buf << "\n";} \
}while(0)

would work (and with truncation, could be done with safety if not reliably via snprintf), but if you're using C++ types anyway, you might want to look at a non-printf-y solution

0
user1765354 On

I was using sprintf wrong. Here's the correct code:

char argString[1024]; sprintf(argString, __VA_ARGS__);

Now argString holds the value of VA_ARGS.