我认为这是printf的包装函数。例如:
my_printf("Hello world\n")
版画
[1] Hello world
要么
[hh:mm:ss] Hello world
我知道我在Linux内核中看到了它,但不确定如何在自己的应用程序中实现它。
在上面的第一个示例中,该数字递增,因此对my_printf的下一个调用将为2。例如
my_printf("Hello universe\n");
版画
[2] Hello universe
用户从不传递通用参数,但仍将其打印出来。
已经提到了使用静态变量的技巧。
难题的第二部分是使用中提供的功能stdarg.h
。
难题的最后一部分是vprintf()
可以用于变量参数列表。
一个样品:
#include#include int my_printf(const char *fmt, ...) { static unsigned counter = 0; int len1 = printf("[%d] ", ++counter); if (len1 <0) return len1; va_list args; va_start(args, fmt); int len2 = vprintf(fmt, args); va_end(args); return len2 <0 ? len2 : len1 + len2; } int main(void) { my_printf("Hello world.\n"); my_printf("%s", "Hello world, again.\n"); for (int i = 2; i <= 4; ++i) my_printf("Hello %d. world.\n", i); }
输出:
#include#include int my_printf(const char *fmt, ...) { static unsigned counter = 0; int len1 = printf("[%d] ", ++counter); if (len1 <0) return len1; va_list args; va_start(args, fmt); int len2 = vprintf(fmt, args); va_end(args); return len2 <0 ? len2 : len1 + len2; } int main(void) { my_printf("Hello world.\n"); my_printf("%s", "Hello world, again.\n"); for (int i = 2; i <= 4; ++i) my_printf("Hello %d. world.\n", i); }
Live Demo on coliru
如果计数器应该是参数而不是static
变量,则my_printf()
可以调整:
#include#include int my_printf(unsigned counter, const char *fmt, ...) { int len1 = printf("[%d] ", counter); if (len1 <0) return len1; va_list args; va_start(args, fmt); int len2 = vprintf(fmt, args); va_end(args); return len2 <0 ? len2 : len1 + len2; } int main(void) { unsigned counter = 0; my_printf(++counter, "Hello world.\n"); my_printf(++counter, "%s", "Hello world, again.\n"); for (int i = 2; i <= 4; ++i) my_printf(++counter, "Hello %d. world.\n", i); }
Live Demo on coliru
递增counter
中my_printf()
不会影响作为参数传递的变量。(C总是按值传递参数。)在那种情况下,counter
必须通过指针传递。