Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 清理调试输出函数?_C_Debugging_C Preprocessor - Fatal编程技术网

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

我想写一个函数,将打印出程序中的错误消息/警告以及文件和行号。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 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,它允许您在不使用额外参数的情况下传递原始字符串。我知道,我编写它的原因与上面的语句类似。只要尝试一下,就会发现缺少一个;之后,否则这是一个非常好的解决方案!