我如何在C中编写一个新的自己的格式说明符?

时间:2016-01-06 16:55:34

标签: c format specifier

是否可以在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地址

4 个答案:

答案 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