chu*_*ica 12 c printf language-lawyer
fprintf()家庭的功能有5级标志人物'-','+',' ','#','0'.
重复标志时指定的行为(如果有)是什么?
#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;
}
Run Code Online (Sandbox Code Playgroud)
使用我的gcc"i686-pc-cygwin/4.9.2",我收到"警告:重复''标志格式[-Wformat =]",所以我认为这是一个正确的行为 - >警告用户并允许重复标记.
在尝试编写格式解析器时,我还没有找到针对此角落问题的C99/C11规范指南.
如果重复允许,以下代码就可以了.如果不允许重复,则第二个0是宽度.然后,说明符具有2米的宽度0和*,这是另一个问题.
// -------v
printf("%00*d\n", 5, 78); // 00078
Run Code Online (Sandbox Code Playgroud)
在我看来,标准在这一点上还不清楚.
gcc的作者显然认为重复的标志是无效的,因为gcc默认发出警告,例如:
printf("%++d\n", 42);
Run Code Online (Sandbox Code Playgroud)
但这并不一定告诉我们标准作者的意图.
标准允许:
零个或多个标志(以任何顺序),用于修改转换规范的含义.
标志是-,+,空间,#和0.我认为,短语"零或多个标志*"专门用于允许组合不同的标志.例如,这:
#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);
}
Run Code Online (Sandbox Code Playgroud)
有效并产生此输出:
| 123|
|123 |
| 0x123|
|0x123 |
|0x123 |
Run Code Online (Sandbox Code Playgroud)
在其他情况下,标准明确是否可以重复构造或不重复构造.例如,long long int不同于long int,并且long int int是语法错误.另一方面,该标准明确指出(N1570 6.7.3p5):
如果同一个限定符在同一个specifier-qualifier-list中出现多次 ,无论是直接还是通过一个或多个
typedefs,行为都与它只出现一次相同.
这里缺少任何此类陈述使我怀疑该标准的作者没有考虑重复相同标志的情况.
如果我对此不正确,并且委员会确实打算将重复标志等同于单个标志,那么您的格式解析器应该将它们视为等效.如果我是正确的,那么重复相同标志的行为是未定义的,并且您的实现可以执行任何您喜欢的操作 - 包括将它们视为等同于单个标志.
在任何一种情况下,如果您愿意,您都可以自由发出警告.即使标准定义了重复标志的行为,它仍然可以说是糟糕的风格,值得警告.