将__VA_ARGS__转换为字符串

时间:2016-12-22 17:30:10

标签: c++ string variadic-macros

我正在尝试重新定义Variadic宏以使用cout而不是printf。这是原始代码:

#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)

我将此转换为以下内容以使用cout而不是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)

出于某种原因,__VA_ARGS__适用于printf,但不适用于sprintf。它也不适用于cout。我想知道将__VA_ARGS__转换为字符串的正确方法,或者使用cout将其打印出来的正确方法。

2 个答案:

答案 0 :(得分:1)

sprintf需要一个额外的参数,数据缓冲区将输出写入。如果不进行更改以提供该缓冲区,则无法将printf替换为sprintf。它也不会返回指向字符串的指针,因此您无法将结果分配给std::string并期望它能够正常工作。如果你操作不安全(假设最大缓冲区长度),那么就像这样简单:

#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)

可以工作(如果不能通过snprintf可靠,可以通过截断来完成),但是如果你还在使用C ++类型,你可能想看看a non-printf-y solution

答案 1 :(得分:1)

我使用的是sprintf错了。这是正确的代码:

onfulfilled

现在argString保存 VA_ARGS 的值。