C 清理调试输出函数?
我想写一个函数,将打印出程序中的错误消息/警告以及文件和行号。C中有两个宏: 但在我看来有个问题。。。当我编写这样的函数时:C 清理调试输出函数?,c,debugging,c-preprocessor,C,Debugging,C Preprocessor,我想写一个函数,将打印出程序中的错误消息/警告以及文件和行号。C中有两个宏: 但在我看来有个问题。。。当我编写这样的函数时: #include <stdio.h> #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define AT __FILE__ ":" TOSTRING(__LINE__) void error(const char *location, const char *msg) { #ifdef DEB
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
#ifdef DEBUG
printf("Error at %s: %s\n", location, msg);
#endif
}
int main(int , char**)
{
error(AT, "fake error");
return 0;
}
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
printf("Error at %s: %s\n", location, msg);
}
int main(int , char**)
{
#ifdef DEBUG
error(AT, "fake error");
#endif
return 0;
}
但是在每次函数调用之前和之后都不编写ifdef DEBUG和endif,这对于这样的任务来说太大了。并消除每一个错误,假错误;手动呼叫也不是很优雅
有什么想法吗?也许内联函数不会有帮助,不是吗?这个构造的一些宏或更改 只需将错误转换为宏:
#ifdef DEBUG
# define ERROR(l, m) error(l, m)
#else
# define ERROR(l, m)
#endif
然后,在函数中编写
ERROR(AT, "fake error");
当然,您也可以简化错误并去掉AT作为第一个参数,直接在宏定义中指定此信息。只需将错误转换为宏:
#ifdef DEBUG
# define ERROR(l, m) error(l, m)
#else
# define ERROR(l, m)
#endif
#ifdef DEBUG
#define ERROR(msg) error(AT, msg)
#else
#define ERROR(msg)
#endif
int main( int argc, char * argv[] )
{
ERROR( "fake error");
return 0;
}
然后,在函数中编写
ERROR(AT, "fake error");
当然,您也可以简化错误并去掉AT作为第一个参数,直接在宏定义中指定此信息。用define替换错误
#ifdef DEBUG
#define ERROR(msg) error(AT, msg)
#else
#define ERROR(msg)
#endif
int main( int argc, char * argv[] )
{
ERROR( "fake error");
return 0;
}
比如:
#ifdef DEBUG
#define error(a,b) printf("Error at %s: %s\n", (a), (b))
#else
#define error(a,b)
#endif
您也可以将AT移动到错误中,而不是每次都传递它将错误替换为define 比如:
#ifdef DEBUG
#define error(a,b) printf("Error at %s: %s\n", (a), (b))
#else
#define error(a,b)
#endif
您也可以将AT移到错误中,而不是每次都传递它。您可以使用此可变宏模拟printf,它以所需的输出写入文件和行号
#define eprintf(...) do {fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);\
fprintf(stderr, __VA_ARGS__);} while(0)
编辑:根据jcsalomon的建议修改了eprintf您可以使用此变量宏来模拟printf,该printf将文件和行号写入所需的输出
#define eprintf(...) do {fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);\
fprintf(stderr, __VA_ARGS__);} while(0)
编辑:根据jcsalomon的建议修改了eprintf,在宏中包装错误确实是正确的方法-我这样写:
#ifdef DEBUG
static void error(const char *file, long line, const char *msg)
{
fprintf(stderr, "Error (%s:%ld): %s\n", file, line, msg);
}
#define error(msg) (error)(__FILE__, __LINE__, msg)
#else
#define error(msg) ((void)0)
#endif
在宏中包装错误确实是正确的方法-我这样写:
#ifdef DEBUG
static void error(const char *file, long line, const char *msg)
{
fprintf(stderr, "Error (%s:%ld): %s\n", file, line, msg);
}
#define error(msg) (error)(__FILE__, __LINE__, msg)
#else
#define error(msg) ((void)0)
#endif
这仅适用于C99或C++0x,最好定义eprintf。。。执行{fprintfstderr,%s:%d:,_文件_,_行_;;fprintfstderr,_VA_参数_;}while0;请注意用do{…}while0包装的语句,更重要的是fprintfstderr,_VA_ARGS_uuu,它允许您在不使用额外参数的情况下传递原始字符串。我知道,我编写它的原因与上面的语句类似。只要尝试一下,就会发现缺少一个;之后,否则这是一个非常好的解决方案!这仅适用于C99或C++0x,最好定义eprintf。。。执行{fprintfstderr,%s:%d:,_文件_,_行_;;fprintfstderr,_VA_参数_;}while0;请注意用do{…}while0包装的语句,更重要的是fprintfstderr,_VA_ARGS_uuu,它允许您在不使用额外参数的情况下传递原始字符串。我知道,我编写它的原因与上面的语句类似。只要尝试一下,就会发现缺少一个;之后,否则这是一个非常好的解决方案!