是否可以在 C 中编写新的格式说明符?例如,假设 %g 是一个格式说明符,它从等价的无符号整数中以 ABCD 格式打印 IP 地址。
int ip_addr = Some integer
printf("ip address = %g", ip_addr);
输出:以 ABCD 格式打印 IP 地址
您将不得不重新实现 printf 函数(更准确地说是它的格式解析函数)。您可以做的是将 printf 包装在支持 IP 地址的函数中,或者执行以下操作:
#define FMT_IP "%d.%d.%d.%d"
#define FMT_IP_ARG(ip) getA(ip), getB(ip), getC(ip), getD(ip)
getX 函数或宏获取表示 IP 地址的给定整数的 X 部分。
然后:
printf("ip address = " FMT_IP "\n", FMT_IP_ARG(ip));
我会选择@chux 的答案,它既简单又便于携带,前提是您可以知道需要多大的临时缓冲区。
但是,如果您使用的是 GNU 库 (glibc),则可以printf
使用新的说明符进行扩展。强烈建议您使用大写字母作为格式代码,因为几乎所有小写格式代码都在使用,其余的可能会被未来的 C/Posix 标准使用。该工具记录在glibc 手册中。
基于 GNU 工具,为 BSD 库编写了一个类似的非常兼容的工具。显然,它可以在 Mac OS X 上使用,尽管我不能保证这一事实。我确实在xprintf(3)和xprintf(5)的 Apple 在线手册页中找到了它。
上面链接的文档中有示例。
添加新的说明符涉及重写printf()
或制作您自己的处理新说明符的函数以及printf()
调用它。这两种方法都很困难。
另一种方法是使用"%s"
和制作您自己的形成字符串的函数。
对于 C99 或更高版本,使用复合文字来形成所需的缓冲区空间。
#include <stdio.h>
#define MYIP_N 16
#define MYIP(ip) myip((char [MYIP_N]){""}, (ip))
char *myip(char *dest, int ip) {
snprintf(dest, MYIP_N, "%d.%d.%d.%d", (ip >> 24) & 255, (ip >> 16) & 255,
(ip >> 8) & 255, (ip >> 0) & 255);
return dest;
}
int main(void) {
int ip1 = 0x01020304;
int ip2 = 0x05060708;
printf("%s %s\n", MYIP(ip1), MYIP(ip2));
return 0;
}
输出
1.2.3.4 5.6.7.8
这适用于printf()
or fprintf()
, sprintf()
, evenputs()
puts(MYIP(ip1));
1.2.3.4
您不能更改标准库函数,尽管您可以编写一个将接受%g
并依次调用printf
.