重复printf说明符标志时的行为是什么?

时间:2015-04-13 17:46:17

标签: c printf language-lawyer

fprintf()系列函数包含5个标记字符'-''+'' ''#',{{1} }。

当标志重复时,指定的行为(如果有)是什么?

'0'

使用我的gcc“i686-pc-cygwin / 4.9.2”我收到“警告:重复''标志格式[-Wformat =]”,所以我认为这是一个正确的行为 - >警告用户并允许重复标记。

在尝试编写格式解析器时,我还没有找到针对此角落问题的C99 / C11规范指南。

如果允许重复,则以下代码可以。如果不允许重复,则第二个#include <stdio.h> int main(void) { printf("% d\n", 12); // 12 printf("%00d\n", 34); // 34 printf("%++d\n", 56); // +56 printf("%00*d\n", 5, 78); // 00078 return 0; } 是宽度。然后说明符有2个宽度00,这是另一个问题。

*

3 个答案:

答案 0 :(得分:5)

在我看来,标准目前还不清楚。

gcc的作者显然认为重复标记无效,因为gcc默认发出警告,例如:

printf("%++d\n", 42);

但这并不一定能告诉我们标准作者的意图。

标准许可:

  

零个或多个标志(以任何顺序),修改转换的含义   说明书

标志为-+空间#0。我认为,短语&#34;零或多个标志*专门用于允许组合不同的标志。例如,这个:

#include <stdio.h>
int main(void) {
    printf("|%6x|\n", 0x123);
    printf("|%-6x|\n", 0x123);
    printf("|%#6x|\n", 0x123);
    printf("|%-#6x|\n", 0x123);
    printf("|%#-6x|\n", 0x123);
}

有效并产生此输出:

|   123|
|123   |
| 0x123|
|0x123 |
|0x123 |

在其他情况下,该标准明确指出是否可以重复构造。例如,long long intlong int不同,long int int是语法错误。另一方面,该标准明确指出(N1570 6.7.3p5):

  

如果相同的限定符出现在同一个中多次    specifier-qualifier-list ,可直接或通过一个或多个    typedefs ,行为与仅出现一次的行为相同。

此处缺少任何此类陈述使我怀疑该标准的作者没有考虑重复相同旗帜的情况。

如果我对此不正确,并且委员会确实打算将重复标志等同于单个标志,那么您的格式解析器应该将它们视为等效。如果我正确,那么重复相同标志的行为是未定义的,您的实现可以做任何您喜欢的事情 - 包括将它们视为等同于单个标志。

在任何一种情况下,如果您愿意,您都可以自由发出警告。即使标准定义了重复旗帜的行为,它仍然可以说是糟糕的风格,值得警告。

答案 1 :(得分:2)

在C标准(7.21.6.1 fprintf函数)中只写了

  

4每个转换规范由字符%引入。   在%之后,以下顺序出现:

     

- 零或多个标志(以任意顺序),修改其含义   转换规范。

所以我想可能会重复标记。否则会有一些限制。

答案 2 :(得分:2)

标准说:

  

7.19.6.1/4修改转换规范含义的零个或多个标志(以任何顺序排列)。

&#34;零个或多个标志&#34;显然是为了允许指定多个标志。有意义的是,如果重复一个标志,它与仅出现一次的标志具有相同的含义。