是否可以在C中编写新的格式说明符?例如,假设%g是格式说明符,它以无符号整数等价物打印A.B.C.D格式的ip地址。
Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'INVALID' Use --force to continue.
输出:以A.B.C.D格式打印IP地址
答案 0 :(得分:5)
您必须重新实现printf函数(更准确地说是它的格式解析函数)。你可以做的是将printf包装在支持ip地址的函数中,或者这样做:
#define FMT_IP "%d.%d.%d.%d"
#define FMT_IP_ARG(ip) getA(ip), getB(ip), getC(ip), getD(ip)
getX函数或宏获取给定整数的X部分代表IP地址。
然后:
printf("ip address = " FMT_IP "\n", FMT_IP_ARG(ip));
答案 1 :(得分:2)
添加一个新的说明符包括重写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()
或fprintf()
,sprintf()
,甚至puts()
puts(MYIP(ip1));
1.2.3.4
答案 2 :(得分:1)
我会选择@chux's answer,如果你知道你需要多大的临时缓冲区,这是简单易用的。
但是,如果您使用的是GNU库(glibc),则可以使用新的说明符扩展printf
。强烈建议您使用大写字母作为格式代码,因为几乎所有小写格式代码都在使用中,其余的可能会被未来的C / Posix标准使用。该工具记录在glibc manual。
基于GNU工具,为BSD库编写了一个类似的非常兼容的工具。显然,它可以在Mac OS X上使用,但我无法保证这一点。我确实在xprintf(3)和xprintf(5)的Apple在线手册页中找到了它。
上面链接的文档中有一些例子。
答案 3 :(得分:0)
您无法更改标准库函数,但您可以编写一个接受%g
的包装函数,然后调用printf
。