C语言 通过宏修改 printf()s 以包含文件和行号信息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15549893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:47:56  来源:igfitidea点击:

Modify printf()s via macro to include file and line number information

c

提问by user138645

I was just wondering if there is some macro-hack we can use, to alter existing printf() statements in a project.

我只是想知道我们是否可以使用一些宏技巧来改变项目中现有的 printf() 语句。

/* file.c */
printf ("%s", strerror(errno));

/* After macro processing, this line would become */
printf ("%s %s %d", strerror(errno), __FILE__, __LINE__);

回答by Some programmer dude

With the caveat in my comment, you could do it using a variadic macro:

有了我评论中的警告,您可以使用可变参数宏来做到这一点:

#define PRINTF_FL(format, ...) \
    printf(format " %s %d", __VA_ARGS__, __FILE__, __LINE__)

回答by kamituel

Try this:

尝试这个:

#define debug(fmt, ...) printf("%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__);

I used name debuginstead of printf, because I don't think you should override standard functions. You could break something.

我使用 namedebug而不是printf,因为我认为您不应该覆盖标准函数。你可以打破一些东西。

Use this like:

像这样使用:

debug("This is debug no %d", 5);

To get output similar to:

要获得类似于以下内容的输出:

program.c:12: this is debug no 5

(file: program.c, line: 12).

(文件:program.c,行:12)。

回答by MOHAMED

to redefine the printfdo not use undefjust define the following printfmacro in your header file

重新定义printf不要使用,undef只需printf在头文件中定义以下宏

#define printf(MESSAGE,args...) { \
  const char *A[] = {MESSAGE}; \
  printf("%s %d",__FILE__,__LINE__); fflush(stdout);\
  if(sizeof(A) > 0) {\
    printf("::"); \
    printf(*A,##args); \
  } else {\
    printf("\n"); \
  }\
}

you can use your new printfmacro in your code in this way

您可以通过printf这种方式在代码中使用新宏

printf(); // it will print only the file name and the line number

or in this way

或以这种方式

printf("debug message any data %d\n", 5);

回答by Eddy_Em

And here is my "half penny".

这是我的“半分钱”。

Function name & debug messages:

函数名称和调试消息:

// debug mode, -DEBUG
#ifdef EBUG
    #define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__)
    #define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \
                    fprintf(stderr, __VA_ARGS__);           \
                    fprintf(stderr, "\n");} while(0)
#else
    #define FNAME()  do{}while(0)
    #define DBG(...) do{}while(0)
#endif //EBUG

Use macro FNAME()to show just name of function & file/line, DBG(text)to show printf-like debug message with info about function name & file/line.

使用宏FNAME()仅显示函数名称和文件/行,DBG(text)以显示类似 printf 的调试消息以及有关函数名称和文件/行的信息。

And something that may be useful for coloured debug & error/warning messages.

以及可能对彩色调试和错误/警告消息有用的东西。

In header file:

在头文件中:

extern int globErr;
#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0)
#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)
#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)
// functions for color output in tty & no-color in pipes
EXTERN int (*red)(const char *fmt, ...);
EXTERN int (*_WARN)(const char *fmt, ...);
EXTERN int (*green)(const char *fmt, ...);

In C file:

在 C 文件中:

int globErr = 0; // errno for WARN/ERR
// pointers to coloured output printf
int (*red)(const char *fmt, ...);
int (*green)(const char *fmt, ...);
int (*_WARN)(const char *fmt, ...);
/*
 * format red / green messages
 * name: r_pr_, g_pr_
 * @param fmt ... - printf-like format
 * @return number of printed symbols
 */
int r_pr_(const char *fmt, ...){
    va_list ar; int i;
    printf(RED);
    va_start(ar, fmt);
    i = vprintf(fmt, ar);
    va_end(ar);
    printf(OLDCOLOR);
    return i;
}
int g_pr_(const char *fmt, ...){
    va_list ar; int i;
    printf(GREEN);
    va_start(ar, fmt);
    i = vprintf(fmt, ar);
    va_end(ar);
    printf(OLDCOLOR);
    return i;
}
/*
 * print red error/warning messages (if output is a tty)
 * @param fmt ... - printf-like format
 * @return number of printed symbols
 */
int r_WARN(const char *fmt, ...){
    va_list ar; int i = 1;
    fprintf(stderr, RED);
    va_start(ar, fmt);
    if(globErr){
        errno = globErr;
        vwarn(fmt, ar);
        errno = 0;
        globErr = 0;
    }else
        i = vfprintf(stderr, fmt, ar);
    va_end(ar);
    i++;
    fprintf(stderr, OLDCOLOR "\n");
    return i;
}

const char stars[] = "****************************************";
/*
 * notty variants of coloured printf
 * name: s_WARN, r_pr_notty
 * @param fmt ... - printf-like format
 * @return number of printed symbols
 */
int s_WARN(const char *fmt, ...){
    va_list ar; int i;
    i = fprintf(stderr, "\n%s\n", stars);
    va_start(ar, fmt);
    if(globErr){
        errno = globErr;
        vwarn(fmt, ar);
        errno = 0;
        globErr = 0;
    }else
        i = +vfprintf(stderr, fmt, ar);
    va_end(ar);
    i += fprintf(stderr, "\n%s\n", stars);
    i += fprintf(stderr, "\n");
    return i;
}
int r_pr_notty(const char *fmt, ...){
    va_list ar; int i;
    i = printf("\n%s\n", stars);
    va_start(ar, fmt);
    i += vprintf(fmt, ar);
    va_end(ar);
    i += printf("\n%s\n", stars);
    return i;
}

In main():

在 main() 中:

if(isatty(STDOUT_FILENO)){ // make color output in tty
    red = r_pr_; green = g_pr_;
}else{ // no colors in case of pipe
    red = r_pr_notty; green = printf;
}
if(isatty(STDERR_FILENO)) _WARN = r_WARN;
else _WARN = s_WARN;

After that you will be able to use coloured output in case running in terminal and non-coloured in case of pipe. Functions redand greenare analogues of printffor coloured output. Function _WARNused in macros to show user message and string for errno: ERRfor case of errors (ends with exit), WARN— analogue of ERRbut without exitand WARNXto show messages without errno.

之后,您将能够在终端中运行时使用彩色输出,而在管道中使用非彩色输出。功能redgreenprintf彩色输出的类似物。_WARN在宏中用于显示用户消息和字符串的函数errnoERR对于错误的情况(以 结尾exit),WARN— 类似于ERR但没有exitWARNX显示没有 的消息errno

回答by Shrikant Khanduri

Define below Macro MYPRINT. Include File name, Line number, Function name and \n

在下面定义宏 MYPRINT。包括文件名、行号、函数名和\n

 #define MYPRINT(str,args...) printf("%s:%d %s() "str"\n",__FILE__,__LINE__,__func__, ##args)