c++ - 在 printf 中使用可以扩展为整数或无值的 MACROS

标签 c++ macros printf variadic-functions

我正在编写一些使用以下宏的 C++ 代码:

#if(PRINT_DEBUG_SYMBOLS)
    #define FILE_NAME __FILE__
    #define LINE_NUMBER __LINE__
#else
    #define FILE_NAME ""
    #define LINE_NUMBER 

我按以下方式使用这些宏:

SendMsg(2000, "Unable to open file %s %d", FILE_NAME, LINE_NUMBER);

如您所见,FILE_NAME 已扩展为文件名或基于 PRINT_DEBUG SYMBOLS 的空字符串。我希望 LINE__NUMBER 有类似的行为。它应该根据 PRINT_DEBUG_SYMBOLS 打印行号或不打印行号。但是没有像空字符串那样的整数等价物,所以当 PRINT_DEBUG_SYMBOLS=0 时,我打印了一些随机整数。我该如何解决这个问题?

这里是 SendMsg() 的定义。我没有修改这个功能的灵 active 。

void SendMsg(int code, char* Msg, ...)
{
    char buffer[256];
    va_list args;
    va_start(args, Msg);
    vsprintf(buffer, Msg, args);
    ostringstream line;
    line<<code<<buffer;
    printf("%s", line.str);
}

最佳答案

一个简单的解决方案是在非调试情况下#define LINE_NUMBER 0,然后使用格式%.d代替%d:

SendMsg(2000, "Unable to open file %s %.d", FILE_NAME, LINE_NUMBER);

这将导致 0 不被打印 [见注释 1],尽管它不会抑制任何空格字符,因此输出在消息末尾仍然会有两个冗余空格字符.可能你不关心这个。

如果您知道 FILE_NAMELINE_NUMBER 都是宏(或类似 __LINE__ 的伪宏)并且 LINE_NUMBER 是一个文字数字,然后您可以将字符串化和字符串连接以生成单个字段:

#define STR_(x) #x
#define STR(x) STR_(x)
#define FILE_LINE FILE_NAME " " STR_(LINE_NUMBER)

SendMsg(2000, "Unable to open file %s", FILE_LINE);

或者您可以更复杂地同时提供格式和值宏:

// FILE_NAME and LINE_NUMBER need to be defined at some point
#if(PRINT_DEBUG_SYMBOLS)
    #define FILE_LINE FILE_NAME, LINE_NUMBER
    #define FL_FMT "%s:%d"
#else
    #define FILE_LINE ""
    #define FL_FMT "%s"
#endif

// ...
SendMsg(2000, "Unable to open file " FL_FMT, FILE_LINE);

注意事项:

  1. 摘自 C11 标准 §7.21.6.1,其中记录了 *printf 格式:

    After the %, the following appear in sequence:

    … — An optional precision that gives the minimum number of digits to appear for the d, i, o, u, x, and X conversions, …. The precision takes the form of a period (.) followed either by an asterisk * (described later) or by an optional decimal integer; if only the period is specified, the precision is taken as zero.

    The conversion specifiers and their meanings are:

    d,i The int argument is converted to signed decimal in the style [−]dddd. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is 1. The result of converting a zero value with a precision of zero is no characters.

关于c++ - 在 printf 中使用可以扩展为整数或无值的 MACROS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34067842/

相关文章:

GCC 中的 CLI 命令表

c++ - 如何将字符串转换为由 C++ 中的字符组成的字符串数组?

c++ - std::set 没有前后成员函数是否有设计原因?

vba - 如何自动从 Excel 中的一个工作表复制数据并将其附加到另一工作表中的现有表?

c - MinGW 海湾合作委员会 : "Unknown conversion type character ' h'"(snprintf)

c - 如何检索字符串的一部分?

c - 从函数传递双值时无法打印答案(C 语言)

c++ - 具有成员函数的 G++ may_alias

c++ - boost::mpi 阻塞 IO 不会被 linux 信号中断

objective-c - c中的模拟器/生成的switch语句范围