我正在编写一些使用以下宏的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()的定义。我不具备修改此功能的灵活性。
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);
}
答案 0 :(得分:1)
一个简单的解决方案是在非调试案例中#define LINE_NUMBER 0
,然后使用格式%.d
代替%d
:
SendMsg(2000, "Unable to open file %s %.d", FILE_NAME, LINE_NUMBER);
这将导致0
无法打印[请参阅注释1],虽然它不会抑制任何空格字符,因此输出仍将在消息末尾有两个冗余空格字符。可能你不关心那个。
如果您知道FILE_NAME
和LINE_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);
摘录自C11标准§7.21.6.1,该文件记录*printf
格式:
...
在
%
之后,以下顺序出现:... - 一个可选的精度,为
d
,i
,o
,u
,x
以及转化X
,....精度采用句点(.
)的形式,后跟星号*
(稍后描述)或可选的十进制整数;如果只指定了句点,则精度为零。...
转换说明符及其含义为:
d,i
int参数在样式[−]dddd
中转换为带符号的十进制数。精度指定要显示的最小位数;如果转换的值可以用更少的数字表示,则使用前导零进行扩展。默认精度为1.转换零值且精度为零的结果不是字符。