[英]How do I define a macro to print file, function, line in cpp?
I am trying to make a print function which prepends the print statement with file, function, and line number.我正在尝试打印 function,它在打印语句前面加上文件、function 和行号。
The function debug("test %d", 1)
should print: function
debug("test %d", 1)
应该打印:
[src/main.cpp:main():8] test 1
This answer claims to do what I want, and almost does it, but doesn't work as-is.这个答案声称可以做我想做的事,并且几乎可以做到,但不能按原样工作。 (And the question is not the same as this one) Using that answer, I was able to come up with this macro:
(而且这个问题与这个问题不一样)使用那个答案,我能够想出这个宏:
#include <cstdio> //needed for printf
#define debug(a, args...) printf("[%s:%s():%d] " #a "\n", __FILE__, __func__ , __LINE__, ##args)
This is extremely close to what I want, but adds quotes around the string, like below.这与我想要的非常接近,但在字符串周围添加了引号,如下所示。 How can I print without the quotes?
没有引号如何打印?
[src/main.cpp:main():8] "test 1"
There are 2 problems with your macro definition:您的宏定义有两个问题:
a
;a
; in this case you cannot simply put the variable next to 2 string literals to do a concatenation. The latter problem can be solved by using a string and the +
operator or simply using multiple printf
s.后一个问题可以通过使用字符串和
+
运算符或简单地使用多个printf
来解决。
If C++20 __VA_OPT__
is available, the following solution could be used.如果 C++20
__VA_OPT__
可用,则可以使用以下解决方案。
#include <cstdio>
#include <utility>
namespace Logging
{
template<typename ...Args>
inline void Debug(size_t lineNumber, char const* filename, char const* functionName, char const* format, Args&&... args)
{
std::printf("[%s:%s():%zu] ", filename, functionName, lineNumber);
std::printf(format, std::forward<Args>(args)...);
std::printf("\n");
}
}
#define debug(format, ...) ::Logging::Debug(__LINE__, __FILE__, __func__, format __VA_OPT__(,) __VA_ARGS__)
Pre C++ 20 you could create a helper object to deal with the case of a sue of the macro with just a single parameter Pre C++ 20 你可以创建一个帮助程序 object 来处理仅使用单个参数的宏的情况
#include <cstdio>
#include <utility>
namespace Logging
{
class Logger
{
public:
Logger(size_t lineNumber, char const* filename, char const* functionName, char const* format)
: m_lineNumber(lineNumber), m_filename(filename), m_functionName(functionName), m_format(format)
{}
template<class ...Args>
inline void Debug(Args&&... args)
{
std::printf("[%s:%s():%zu] ", m_filename, m_functionName, m_lineNumber);
std::printf(m_format, std::forward<Args>(args)...);
std::printf("\n");
}
private:
size_t m_lineNumber;
char const* m_filename;
char const* m_functionName;
char const* m_format;
};
}
#define debug(format, ...) ::Logging::Logger(__LINE__, __FILE__, __func__, format).Debug(__VA_ARGS__)
Replace #a
with just a
:仅将
#a
替换为a
:
#define debug(a, args...) printf("[%s:%s():%d] " a "\n", __FILE__, __func__, __LINE__, ##args)
A single #
followed by a macro parameter stringifies the parameter.单个
#
后跟宏参数将参数字符串化。 IOW, it takes whatever the caller passes into the parameter and makes a string literal out of it. IOW,它接受调用者传递给参数的任何内容,并从中生成字符串文字。 For example:
例如:
#define macro(a) #a
macro(1)
would be "1"
, macro(x+y)
would be "x+y"
, etc. macro(1)
将是"1"
, macro(x+y)
将是"x+y"
,等等。
If the parameter contains quote characters, they will be stored as actual characters in the string literal, which is not what you want in this situation.如果参数包含引号字符,它们将作为实际字符存储在字符串文字中,这不是您在这种情况下想要的。 Your parameter is being passed a string literal that you want to use as-is, so simple macro replacement will suffice, so you need to drop the
#
.您的参数正在传递一个您想按原样使用的字符串文字,因此简单的宏替换就足够了,因此您需要删除
#
。 You want the compiler to see "[%s:%s():%d] " "test %d" "\n"
and thus merge them together into "[%s:%s():%d] test %d\n"
, not to see "[%s:%s():%d] " "\"test %d\"" "\n"
and merge them into "[%s:%s():%d] \"test %d\"\n"
, which is what you are seeing happen in your original code.您希望编译器看到
"[%s:%s():%d] " "test %d" "\n"
并因此将它们合并到"[%s:%s():%d] test %d\n"
,看不到"[%s:%s():%d] " "\"test %d\"" "\n"
并将它们合并到"[%s:%s():%d] \"test %d\"\n"
,这是您在原始代码中看到的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.