Существует ли общий спецификатор преобразования для printf?

Я хочу напечатать значение переменной без указания его типа.

В c, я могу сделать

int main(int argc, char **argv) { int i = 1; float f = 0.1; char s[] = "s"; printf("%i\n", i); printf("%f\n", f); printf("%s", s); return 0; } 

но я ожидаю:

 int main(int argc, char **argv) { int i = 1; float f = 0.1; char s[] = "s"; printf("%any_type\n", i); printf("%any_type\n", f); printf("%any_type", s); return 0; } 

вопрос: есть ли %any_type в C?

В C11 вы можете написать общую функцию для печати любого типа и продолжать добавлять свой настраиваемый тип к этой функции.

 #define print_any(X) _Generic((X), int: print_int, \ default: print_unknown, \ float: print_float)(X) int print_int(int i) { return printf("%d\n", i); } int print_float(float f) { return printf("%f\n", f); } int print_unknown(...) { return printf("ERROR: Unknown type\n"); } 

Вы также можете автоматизировать генерацию функций, как показано ниже.

 #define GEN_PRINT(TYPE, SPECIFIER_STR) int print_##TYPE(TYPE x) { return printf(SPECIFIER_STR "\n", x);} GEN_PRINT(int, "%d"); GEN_PRINT(char, "%c"); GEN_PRINT(float, "%f"); 

Использование будет:

 int main(int argc, char **argv) { int i = 1; float f = 0.1; char s[] = "s"; print_any(i); print_any(f); print_any(s); return 0; } 

Нет, вам нужно указать правильный спецификатор формата.

В C11 вы можете автоматизировать вычисление правильного спецификатора формата с помощью _Generic сочетании с макросом. Однако вам нужно повторить имя переменной (один раз для вычисления спецификатора и один раз, чтобы указать переменную как аргумент).

Для более подробной информации прочитайте эту ссылку .

Нет, printf – это так называемая вариационная функция , что означает, что он может принимать любые числа / типы параметров.

Проблема (ну, одна из них) с вариационными функциями в classическом C состоит в том, что параметры не являются безопасными типами, то есть – вызываемая функция не имеет представления о типе параметров.

Вот почему переменные набираются с использованием строки формата для начала, printf не имеет представления о том, является ли переданное значение указателем, целочисленным или каким-либо другим типом, и нужно посмотреть строку формата, чтобы выяснить, в каком формате отображать Значение.

Это, к сожалению, также открывает возможность ошибок, если строка формата неверна, например, говоря, что значение является указателем на что-то, когда оно действительно является целым числом, программа может сбой (а точнее, вызвать неопределенное поведение) от попытки получить доступ к значению не указателя в качестве указателя.

Таких вещей нет. Мы должны сказать, в каком формате мы собираемся напечатать это значение.