4

是否可以在 C 中编写新的格式说明符?例如,假设 %g 是一个格式说明符,它从等价的无符号整数中以 ABCD 格式打印 IP 地址。

int ip_addr = Some integer

printf("ip address = %g", ip_addr);

输出:以 ABCD 格式打印 IP 地址

4

4 回答 4

6

您将不得不重新实现 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));
于 2016-01-06T17:01:29.000 回答
2

我会选择@chux 的答案,它既简单又便于携带,前提是您可以知道需要多大的临时缓冲区。

但是,如果您使用的是 GNU 库 (glibc),则可以printf使用新的说明符进行扩展。强烈建议您使用大写字母作为格式代码,因为几乎所有小写格式代码都在使用,其余的可能会被未来的 C/Posix 标准使用。该工具记录在glibc 手册中。

基于 GNU 工具,为 BSD 库编写了一个类似的非常兼容的工具。显然,它可以在 Mac OS X 上使用,尽管我不能保证这一事实。我确实在xprintf(3)xprintf(5)的 Apple 在线手册页中找到了它。

上面链接的文档中有示例。

于 2016-01-06T20:54:03.487 回答
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()or fprintf(), sprintf(), evenputs()

puts(MYIP(ip1));

1.2.3.4
于 2016-01-06T17:29:17.187 回答
0

您不能更改标准库函数,尽管您可以编写一个将接受%g并依次调用printf.

于 2016-01-06T17:00:30.317 回答