在C语言中,是否可以编写新的格式说明符?例如,假设%g是一个格式说明符,它可以从无符号整数等效值中以A.B.C.D格式打印IP地址。
int ip_addr = Some integer
printf("ip address = %g", ip_addr);
输出:以A.B.C.D格式打印IP地址
您需要重新实现printf函数(更准确地说是其格式解析函数)。您可以在支持IP地址的函数内部包装printf,或者执行以下操作:
#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));
getA
、getB
等是什么? - Jabberwocky然而,如果你使用 GNU 库(glibc),你可以用新的格式说明符扩展printf
。强烈建议使用大写字母作为格式代码,因为几乎所有小写格式代码都在使用中,其余的可能会被未来的 C/Posix 标准使用。这个功能在glibc 手册中有文档。
基于 GNU 功能,为 BSD 库编写了一个类似的兼容性很好的工具。显然,在 Mac OS X 上可用,但我不能保证这一点。我在苹果的在线手册xprintf(3)和xprintf(5)中找到了它。
上述文档中有示例。添加新的格式说明符需要重新编写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()
或fprintf()
,sprintf()
甚至puts()
。puts(MYIP(ip1));
1.2.3.4
虽然您无法更改标准库函数,但可以编写一个包装函数,该函数将接受%g
并调用printf
。
printf
(或 vprintf
) 不是一件容易的事情。 - Jérôme Pouiller
printf()
添加格式说明符。不过,你可以编写一个可变参数函数,为每个格式说明符调用printf()
和自定义程序来处理你的说明符,此外,你可以让你的程序调用你的printf()
函数并使用相同的名称。但我不建议这样做。 - Iharob Al Asimi"%g"
,它用于double
类型。 - chux - Reinstate Monica