我想使用sprintf
来格式化一些浮点值,但我似乎无法正确格式化。我尝试过";CCD_ 2";作为格式字符串,但这不是我想要的。";CCD_ 3";带有有效数字的说明符似乎对我需要填充的其他情况也没有帮助。
"1.6f"
Actual output: 1.000000
Expected Output: 1
"g"
Actual output: 1.1
Expected Output: 1.100000
由于没有打印说明符来满足OP的详细需求("%g"
已接近(,因此需要进行一些测试。
为了满足";除非浮子是完整的";,用modf()
(或float
的C中的modff()
(测试该值是否完整。函数返回小数部分。
// Illustrative code with printf vs sprintf
void mzkoops56_print(float x) {
float ipart;
if (modf(x, &ipart) == 0.0) {
printf("%.0fn", x);
} else {
printf("%.6fn", x);
}
}
这将打印非整数值,如0.999996、1.000004,这些数值接近带小数的整数值。
mzkoops56_print(nextafterf(1.0,0));
mzkoops56_print(1.0);
mzkoops56_print(nextafterf(1.0,2));
mzkoops56_print(1.1f);
1.000000
1
1.000000
1.100000
没有标准的说明符,但glibc支持自定义说明符。下面是一个示例实现:
#include <printf.h>
#include <cmath>
#include <cstdio>
int double_format(FILE *stream, const printf_info *info,
const void *const *args) {
const double d = **reinterpret_cast<double const *const *>(args);
if (std::trunc(d) == d) {
return std::fprintf(stream, "%g", d);
}
int width = info[0].width;
if (width == -1) width = 6; // defaults to 6
return std::fprintf(stream, "%.*f", width, d);
}
int double_format_arg_info(const struct printf_info *, size_t n, int *argtypes,
int *size) {
if (n > 0) {
argtypes[0] = PA_DOUBLE;
size[0] = sizeof(double);
}
return 1;
}
int main() {
register_printf_specifier('F', double_format, double_format_arg_info);
std::printf("%4F && %4Fn", 1.0, 1.1);
}
输出为1 && 1.1000
。
演示
是否有一个带有sprintf的格式字符串,除非浮点是完整的,否则它会填充?
不,没有。您必须自己编写这样的功能。算法基本上是:
- 使用
%.6f
打印到临时字符串 - 检查该字符串是否以
.000000
结尾- 如果是,请删除
.000000
- 如果是,请删除