如何用C编写自己的新格式说明符?

如何用C编写自己的新格式说明符?,c,format,specifier,C,Format,Specifier,可以用C写一个新的格式说明符吗?例如,假设,%g是一个格式说明符,它以a.B.C.D格式从等效的无符号整数打印ip地址 int ip_addr = Some integer printf("ip address = %g", ip_addr); 输出:以A.B.C.D格式打印ip地址您不能更改标准库函数,尽管您可以编写一个包装函数,该函数将接受%g,并反过来调用printf您必须重新实现printf函数(更准确地说是其格式解析函数)。您可以将printf包装到支持ip地址的函数中,或者执行以

可以用C写一个新的格式说明符吗?例如,假设,%g是一个格式说明符,它以a.B.C.D格式从等效的无符号整数打印ip地址

int ip_addr = Some integer

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

输出:以A.B.C.D格式打印ip地址

您不能更改标准库函数,尽管您可以编写一个包装函数,该函数将接受
%g
,并反过来调用
printf

您必须重新实现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()
,或者编写自己的函数来处理新说明符以及
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;
}

这适用于
printf()
fprintf()
sprintf()
,甚至
put()

如果你能知道你需要多大的临时缓冲区,我会选择一个简单且可移植的

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

基于GNU工具,为BSD库编写了一个类似的非常兼容的工具。显然,它可以在MacOSX上使用,尽管我不能保证这一事实。我确实在和的苹果在线手册页上找到了它


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

您可以编写任何您想要的内容,但不能将格式说明符添加到标准库函数
printf()
。但是,您可以编写一个变量函数,为每个格式说明符调用
printf()
,并为说明符编写一个自定义例程,此外,您还可以让程序调用
printf()
函数,并使用相同的名称。但是我不建议这样做。步骤1)避免使用现有的格式说明符,如
“%g”
,它用于
。嗯,IP有32位,应该是无符号的
int
是个坏主意,这两个原因都有。什么是
getA
getB
等等?@MichaelWalz请参见OP中的a、B、C和D。问题是要编写格式说明符,而不是从int中获取这些值。也许你应该在问题中澄清这一点。Michael完成。谢谢。我想知道你怎么能写出这样的函数。以编程方式调用
printf
(或
vprintf
)并不容易。
#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
puts(MYIP(ip1));

1.2.3.4