我需要:
printf( "%.2f\n", input ); // handles 1 and 3 but not 2
printf( "%.2g\n", input ); // handles 1 and 2 but not 3
cout << setprecision( 2 ) << input << endl; // handles 1 and 2 but not 3
是否有printf
或cout
选项可以让我处理所有这些?
答案 0 :(得分:4)
C11标准中提到%f
和%F
(7.21.6.1:8):
表示浮点数的双参数在样式[ - ] ddd.ddd中转换为十进制表示法,其中小数点字符后面的位数等于精度指定。如果缺少精度,则取6;如果精度为零且未指定#flag,则不显示小数点字符。如果出现小数点字符,则在其前面至少出现一个数字。该值四舍五入到适当的位数。
这是一个C片段,可以在malloc
ed bloc t
中生成您想要的内容,然后您需要释放它。如果您使用C99编写,也可以考虑使用可变长度数组。
下面的代码没有引入任何额外的转换近似值(如果你的printf
打印正确的舍入转换为十进制,下面的代码也是如此),并适用于所有浮点值。
#include <stdio.h>
#include <stdlib.h>
…
int len = snprintf(0, 0, "%.2f", input);
if (len < 0) fail();
char *t = malloc((size_t)len + 1);
if (!t) fail();
if (sprintf(t, "%.2f", input) < 0) fail();
len--;
if (t[len] == '0') {
len--;
if (t[len] == '0') {
len--;
if (t[len] == '.') len--;
}
t[len + 1] = '\0';
}
答案 1 :(得分:1)
我不知道任何格式说明符可以满足您的要求。
在将值传递给单独的格式说明符之前预先消化值可能会起作用。例如:
if( nFractional > 0 )
printf("%d.%d", nWhole, nFractional );
else
printf("%d", nWhole );
你可能已经知道了这一点。
答案 2 :(得分:0)
我认为另一种选择是使用asprintf()函数:它自动动态分配一个适当长度的字符串。一旦存储了字符串,就可以删除尾随零/点:
...
float num;
...
char *digits;
int i=asprintf(&digits, "%.2f", num)-1;
for(; digits[i] !='.'; i--)
if (digits[i] == '0') digits[i] = NULL; else break;
if (digits[i] == '.') digits[i] = NULL;
printf("%s\n", digits);
free(digits);
...
答案 3 :(得分:0)
可悲的是,没有办法强制流使用printf
的{{1}}行为。因此,处理此问题的唯一方法是根据需要手动修剪小数位。我已经添加了一个处理此问题的C ++代码示例:
%f
string fullfloat(static_cast<size_t>(log10(numeric_limits<declval(input)>::max())) + 5U, '\0'); // Adding 1 for the 10s place, 1 for the '.' 2 for the decimal places, and 1 for the null
const size_t length = size(fullfloat) - sprintf(data(fullfloat), "%.2f", input );
*(--mismatch(rbegin(fullfloat) + length, next(rbegin(fullfloat), 3U + length), "00.").first) = '\0';
现在将包含正确的字符串,但由于它的大小将超出应用的fullfloat
字符,因此将其用于打印属性的唯一方法是使用{{1 }}:
'\0'