printf 的参数用作格式说明符的参数

Argument to printf to be used as an argument to format specifier

假设我有以下功能:

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)注入现有格式说明符?

您可以使用带有 printf 的星号来指定宽度或精度由参数给出 – 无需创建动态格式字符串。

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

手册页的 printf(3):

Precision

An optional precision, in the form of a period (.) followed by an optional decimal digit string. Instead of a decimal digit string one may write * or *m$ (for some decimal integer m) to specify that the precision is given in the next argument, or in the m-th argument, respectively, which must be of type int. If the precision is given as just ., the precision is taken to be zero. A negative precision is taken as if the precision were omitted. This gives the minimum number of digits to appear for d, i, o, u, x, and X conversions, the number of digits to appear after the radix character for a, A, e, E, f, and F conversions, the maximum number of significant digits for g and G conversions, or the maximum number of characters to be printed from a string for s and S conversions.

printf() 格式字符串不需要是常量文本字符串。也可以是字符串变量或包含格式说明符的字符数组。

char fmt[256];
int  lVal = 5;

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

通过使用字符串作为格式说明符,只要提供给 printf() 函数的参数列表与格式字符串一致,您就可以进行任何修改。

您还可以通过连接格式说明符的片段来构建完整的格式字符串来进行快速更改,或者您可以使用 sprintf().

等函数构建格式说明符字符串