printf/snprintf格式字符%N是什么意思?(不是%n)

4

我正在查看一些旧代码,发现了以下内容:

char buf[...];
int i = 1, j =2;
snprintf(buf, "%d-blah_%d-blah_%N", i, j);

请注意只有两个可变参数被传递,但有3个格式化字符串。

它会打印:

1-blah_2-blah_0

无法在任何文档中找到此信息。 %N 是什么意思?


“%N”是存在的吗?我很难找到相关的参考资料。 - tadman
9
你可能正在看到未定义的行为,或者你正在看到一个特定于实现的扩展。你使用的编译器是什么? - Oliver Charlesworth
@OliverCharlesworth 在 CentOS 上使用普通的 GCC。没有什么特别的。snprintf 似乎来自 stdio.h。 - marathon
@marathon 刚在 gcc-4.8.1 上运行,输出为:"1-blah_2-blah_%N"。 - Jonathan Mee
2个回答

7
根据标准文档(例如 POSIX 的 printf),它没有定义作用(因此 %N 可能是 未定义行为,并且在标准中肯定是未指定的行为)。
然而,GNU glibc 提供了自定义 printf的能力。你的程序可能已经在其他地方使用register_printf_function注册了处理%N的函数。这不是标准,而且只适用于GNU glibc(虽然这是一个方便的技巧,但你不能教GCC format函数属性知道这个技巧)。

1
这是微软CRT中的一个有趣案例。看起来%N被视为大小说明符,但最终它被忽略了。
您可以在<VSDIR>/VC/crt/src/output.c中找到源代码,对于VS2013,您将找到以下行:
enum CHARTYPE {
    ...
    CH_SIZE,            /* 'h', 'l', 'L', 'N', 'F', 'w' */
    ...
};

'N'也被用于查找状态表。文档中没有提到, 也没有提到'F'。仔细检查源代码 (case ST_SIZE),发现'N', 'F''L'(尽管文档中没有!)是无操作大小修饰符。

因此,在您的情况下,对于VS2013,您将获得1-blah_2-blah_,没有尾随0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接