Каково поведение при повторении флага спецификатора printf?
fprintf()
семейство функций имеет 5 флаг символы '-'
, '+'
, ' '
, '#'
, '0'
.
каково указанное поведение, если таковое имеется, когда флаг повторное?
#include <stdio.h>
int main(void) {
printf("% dn", 12); // 12
printf("%00dn", 34); // 34
printf("%++dn", 56); // +56
printf("%00*dn", 5, 78); // 00078
return 0;
}
С моим gcc "i686-pc-cygwin / 4.9.2" я получаю "предупреждение: повторенный флаг '' в формате [-Wformat=]", поэтому я предполагаю, что это правильное поведение--> предупредить пользователя и разрешить повторный флаг.
мне еще предстоит найти C99/C11 руководство по спецификации для этой угловой проблемы найдено при попытке написать синтаксический анализатор формата.
если повторение разрешено, следующий код в порядке. Если повторение не допускается, 2nd 0
- это ширина. Тогда спецификатор имеет 2 ширины 0
и *
, который является еще одной проблемой.
// -------v
printf("%00*dn", 5, 78); // 00078
3 ответов
на мой взгляд, стандарт неясен по этому вопросу.
авторы gcc явно придерживались мнения, что повторяющиеся флаги недействительны, поскольку gcc выдает предупреждение по умолчанию для чего-то вроде:
printf("%++d\n", 42);
но это не обязательно говорит нам, что имели в виду авторы стандарта.
стандартные разрешения:
ноль или больше флаги (в любом порядке), которые изменяют смысл преобразования спецификация.
флаги -
, +
, пробел, #
и 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);
}
является допустимым и производит этот вывод:
| 123|
|123 |
| 0x123|
|0x123 |
|0x123 |
в других контекстах стандарт явно указывает, может ли конструкция повторяться или не повторяться. Например, long long int
отличается от long int
и long int int
ошибка синтаксиса. С другой стороны, стандарт явно говорит (N1570 6.7.3p5), что:
если один и тот же классификатор появляется более одного раза в одном и том же спецификатор-квалификатор-список, или сразу или через одно или больше
typedefs
, поведение такое же, как если бы он появился только один раз.
отсутствие любого такого заявления здесь заставляет меня подозревать, что авторы стандарта не рассмотрим случай повторения одного и того же флага.
если я ошибаюсь в этом, и комитет намеревался, чтобы повторяющийся флаг был эквивалентен одному флагу, то ваш синтаксический анализатор формата должен рассматривать их как эквивалентные. Если я прав, то поведение повторения одного и того же флага не определено, и ваша реализация может делать все, что угодно, включая обращение с ними как с эквивалентом одного флага.
в любом случае, вы можете выпустить предупреждение, если хотите. Даже если стандарт определяет поведение повторяющегося флага, это все еще, возможно, плохой стиль и стоит предупредить.
в стандарте C (7.21.6.1 функция fprintf) написано только то, что
4 каждая спецификация преобразования вводится символ %. После % последовательно отображаются следующие значения:
- ноль или более флагов (в любом порядке), которые изменяют смысл спецификация преобразования.
поэтому я полагаю, что флаги могут быть повторены. Иначе были бы какие-то ограничения.
стандарт говорит:
7.19.6.1 / 4 ноль или более флагов (в любом порядке), которые изменяют значение спецификации преобразования.
" ноль или более флагов", очевидно, предназначен для того, чтобы указать более одного флага. Имеет смысл, что если флаг повторяется, он имеет то же значение, что и флаг, появляющийся только один раз.