(GCC) Знак доллара в строке формата printf

Я видел следующую строку в исходном коде, написанном на C:

printf("%2$d %1$d", a, b);

Что это значит?

Ответ 1

Это расширение для языка, добавленного POSIX (поведение, совместимое с C11, должно быть таким, как описано в ответе @chux). Обозначение %2$d означает то же, что и %d (выводимое целое число со знаком), за исключением того, что он форматирует параметр с заданным номером на основе 1 (в вашем случае это второй параметр, b).

Итак, когда вы запускаете следующий код:

#include <stdio.h>
int main() {
    int a = 3, b = 2;
    printf("%2$d %1$d", a, b);
    return 0;
}

вы получите 2 3 в стандартном выпуске.

Более подробную информацию можно найти на страницах printf.

Ответ 2

В C spec C11dr 7.21.6.1

В качестве части формата печати первый % в "%2$d %1$d" вводит директиву. Эта директива может иметь различные флаги, ширину, точность, модификатор длины и, наконец, спецификатор преобразования. В этом случае 2 - ширина. Следующий символ $ не является ни префиксом, ни модификатором длины, ни спецификатором преобразования. Таким образом, поскольку спецификация преобразования недействительна,

... поведение undefined. C11dr 7.21.6.1 9

Спецификация C обсуждает будущие направления библиотек. Буквы нижнего регистра могут быть добавлены в будущем, а другие символы могут использоваться в расширениях. Конечно, $ не является строчной буквой, поэтому это хорошо для будущего. Это, безусловно, соответствует роли "другого персонажа", поскольку $ не является даже частью набора символов C.

В различных реализациях * nix $ используется как описано в Руководстве для программистов Linux PRINTF (3). $, наряду с предыдущим целым, определяет индекс аргумента ширины.