Аргумент для printf, который будет использоваться в качестве аргумента для спецификатора формата - PullRequest
0 голосов
/ 02 июля 2018

Предположим, у меня есть следующая функция:

void fprint(float f, int ds) {
    printf("%.%df\n", ds, f);
}

Я хочу, чтобы вызывающая сторона указала число с плавающей точкой для печати, а также количество цифр после десятичной точки. (указывается спецификатором .%d)

Однако при компиляции я получаю 2 предупреждения:

./sprint.h: In function ‘fprint’:
./sprint.h:19:14: warning: conversion lacks type at end of format [-Wformat=]
     printf("%.%df\n", ds, f);
          ^

и

./sprint.h:19:12: warning: too many arguments for format [-Wformat-extra-args]
     printf("%.%df\n", ds, f);
            ^~~~~~~~~

И когда он вызывается: fprint(3.1422223f, 3);, он выдает: %df Я также попытался поменять местами порядок аргументов в объявлении функции, но он выдает те же предупреждения.

У меня вопрос: как я могу добавить спецификатор формата (например, %d в данном случае) в существующий спецификатор формата?

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Строка формата printf() не обязательно должна быть постоянной текстовой строкой. Это также может быть строковая переменная или массив символов, содержащий спецификатор формата.

char fmt[256];
int  lVal = 5;

strcpy (fmt, "this %d\n");
printf (fmt, lVal);

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

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

0 голосов
/ 02 июля 2018

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

printf("%.*f", ds, f);

printf (3) для man-страниц:

Точность

Необязательная точность в виде точки (.), за которой следует необязательная строка десятичных цифр. Вместо строки десятичной цифры можно написать * или *m$ (для некоторого десятичного целого числа m) , чтобы указать, что точность указана в следующем аргументе или в m-й аргумент, соответственно, , который должен иметь тип int. Если точность задана как ., точность принимается равной нулю. Отрицательная точность берется так, как если бы точность была опущена. Это дает минимальное количество цифр для преобразования d, i, o, u, x и X, количество цифр после радикального символа для a , A, e, E, f и F преобразований, максимальное количество значащих цифр для преобразований g и G или максимальное количество символов, которые будут напечатаны из строка для s и S преобразований.

...