我只是想知道是否有一些我们可以使用的宏hack来改变项目中现有的printf()语句.
/* file.c */
printf ("%s", strerror(errno));
/* After macro processing, this line would become */
printf ("%s %s %d", strerror(errno), __FILE__, __LINE__);
Run Code Online (Sandbox Code Playgroud)
Som*_*ude 10
有了我的评论中的警告,你可以使用可变参数宏来做到这一点:
#define PRINTF_FL(format, ...) \
printf(format " %s %d", __VA_ARGS__, __FILE__, __LINE__)
Run Code Online (Sandbox Code Playgroud)
试试这个:
#define debug(fmt, ...) printf("%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__);
Run Code Online (Sandbox Code Playgroud)
我使用名称debug而不是printf,因为我认为你不应该覆盖标准函数.你可以打破一些东西.
使用它像:
debug("This is debug no %d", 5);
Run Code Online (Sandbox Code Playgroud)
要获得类似于的输出:
program.c:12: this is debug no 5
Run Code Online (Sandbox Code Playgroud)
(档案:program.c,行:12).
这是我的“半便士”。
\n\n// debug mode, -DEBUG\n#ifdef EBUG\n #define FNAME() fprintf(stderr, "\\n%s (%s, line %d)\\n", __func__, __FILE__, __LINE__)\n #define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \\\n fprintf(stderr, __VA_ARGS__); \\\n fprintf(stderr, "\\n");} while(0)\n#else\n #define FNAME() do{}while(0)\n #define DBG(...) do{}while(0)\n#endif //EBUG\nRun Code Online (Sandbox Code Playgroud)\n\n使用宏FNAME()仅显示函数名称和文件/行,DBG(text)以显示类似 printf 的调试消息,其中包含有关函数名称和文件/行的信息。
extern int globErr;\n#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0)\n#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)\n#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)\n// functions for color output in tty & no-color in pipes\nEXTERN int (*red)(const char *fmt, ...);\nEXTERN int (*_WARN)(const char *fmt, ...);\nEXTERN int (*green)(const char *fmt, ...);\nRun Code Online (Sandbox Code Playgroud)\n\nint globErr = 0; // errno for WARN/ERR\n// pointers to coloured output printf\nint (*red)(const char *fmt, ...);\nint (*green)(const char *fmt, ...);\nint (*_WARN)(const char *fmt, ...);\n/*\n * format red / green messages\n * name: r_pr_, g_pr_\n * @param fmt ... - printf-like format\n * @return number of printed symbols\n */\nint r_pr_(const char *fmt, ...){\n va_list ar; int i;\n printf(RED);\n va_start(ar, fmt);\n i = vprintf(fmt, ar);\n va_end(ar);\n printf(OLDCOLOR);\n return i;\n}\nint g_pr_(const char *fmt, ...){\n va_list ar; int i;\n printf(GREEN);\n va_start(ar, fmt);\n i = vprintf(fmt, ar);\n va_end(ar);\n printf(OLDCOLOR);\n return i;\n}\n/*\n * print red error/warning messages (if output is a tty)\n * @param fmt ... - printf-like format\n * @return number of printed symbols\n */\nint r_WARN(const char *fmt, ...){\n va_list ar; int i = 1;\n fprintf(stderr, RED);\n va_start(ar, fmt);\n if(globErr){\n errno = globErr;\n vwarn(fmt, ar);\n errno = 0;\n globErr = 0;\n }else\n i = vfprintf(stderr, fmt, ar);\n va_end(ar);\n i++;\n fprintf(stderr, OLDCOLOR "\\n");\n return i;\n}\n\nconst char stars[] = "****************************************";\n/*\n * notty variants of coloured printf\n * name: s_WARN, r_pr_notty\n * @param fmt ... - printf-like format\n * @return number of printed symbols\n */\nint s_WARN(const char *fmt, ...){\n va_list ar; int i;\n i = fprintf(stderr, "\\n%s\\n", stars);\n va_start(ar, fmt);\n if(globErr){\n errno = globErr;\n vwarn(fmt, ar);\n errno = 0;\n globErr = 0;\n }else\n i = +vfprintf(stderr, fmt, ar);\n va_end(ar);\n i += fprintf(stderr, "\\n%s\\n", stars);\n i += fprintf(stderr, "\\n");\n return i;\n}\nint r_pr_notty(const char *fmt, ...){\n va_list ar; int i;\n i = printf("\\n%s\\n", stars);\n va_start(ar, fmt);\n i += vprintf(fmt, ar);\n va_end(ar);\n i += printf("\\n%s\\n", stars);\n return i;\n}\nRun Code Online (Sandbox Code Playgroud)\n\nif(isatty(STDOUT_FILENO)){ // make color output in tty\n red = r_pr_; green = g_pr_;\n}else{ // no colors in case of pipe\n red = r_pr_notty; green = printf;\n}\nif(isatty(STDERR_FILENO)) _WARN = r_WARN;\nelse _WARN = s_WARN;\nRun Code Online (Sandbox Code Playgroud)\n\n之后,您将能够在终端中运行时使用彩色输出,在管道中运行时使用非彩色输出。函数red和与彩色输出green类似。printf宏中使用的函数_WARN显示用户消息和字符串errno:ERR对于错误情况(以 结尾exit),WARN\xe2\x80\x94 类似ERR但不带exit并WARNX显示不带消息errno。