C 指定宽度、指定填充数字和指定精度的snprintf浮点

C 指定宽度、指定填充数字和指定精度的snprintf浮点,c,c99,C,C99,我有一个浮点f=1.23456。 我想将其格式化为字符串,如下所示: M 01.23 M 01.2345 空间取决于可变精度 我目前的代码是: snprintf(buf, 10, "M%02.*f", precision, f); 但是输出不是右对齐的->|M01.234 | 有什么方法可以得到我想要的吗?您还需要通过另一个*指定总位数。您还需要一个更大的缓冲区—10字节的缓冲区不够大,无法容纳长度为10的字符串。此外,打印到4 d.p.的值将是1.2346,而不是1.2345

我有一个浮点
f=1.23456
。 我想将其格式化为字符串,如下所示:

M    01.23
M  01.2345
空间取决于可变精度

我目前的代码是:

snprintf(buf, 10, "M%02.*f", precision, f);  
但是输出不是右对齐的->
|M01.234 |


有什么方法可以得到我想要的吗?

您还需要通过另一个
*
指定总位数。您还需要一个更大的缓冲区—10字节的缓冲区不够大,无法容纳长度为10的字符串。此外,打印到4 d.p.的值将是
1.2346
,而不是
1.2345

#include <stdio.h>

int main(void)
{
    double f = 1.23456;
    for (int precision = 2; precision < 6; precision += 2)
    {
        char buffer[32];
        snprintf(buffer, sizeof(buffer), "M%*s%0*.*f", 9 - (precision+3), "", precision+3, precision, f);
        printf("|%s|\n", buffer);
    }
    return 0;
}
9-(精度+3)
有点精致;如果精度大于6,则不一定得到所需的结果-或者如果值超出[0.0..10.0]范围,等等。
+3
(重复)也有点微妙;如果打印的值为10.00或更大,则需要更改为4以获得前导0(但您希望
010.2346
还是
10.2346
?)。零的精度也需要特别注意。您要求的是一种精细的格式,因为它不是标准格式。对于较大的数字、较大的精度、较小的数字或负数,会发生什么情况?不清楚。这就完成了精度的两个示例和一个示例值的必要工作,并显示了如何处理变化,但这不是一个完全通用的解决方案。例如,您可能需要确定
log10(f)
,以了解使用什么来代替
3

在评论中澄清之后 总之,要求如下:

  • 这些值的范围为[0.00..100.00](包括0.00,不包括100.00)
  • 小数点前应打印两位数字,必要时带一个或两个前导零
  • 小数点后应打印1-6位数字,具体取决于精度值
  • 数字应在9个字符的字段中右对齐,小数点前的2位数字前需要空格
  • 数字(和任何前导空格)前面应加字母M
这段代码相当全面地演示了原始解决方案可以完成这项工作,但它使用了更多的变量,因此更容易看到发生了什么

#include <stdio.h>

int main(void)
{
    enum { WIDTH = 9 };
    for (double f = 1.2345678E-7; f < 100.0; f *= 10.0)
    {
        for (int precision = 1; precision <= 6; precision++)
        {
            char buffer[32];
            int f_width = precision + 3;    // decimal point and 2 digits before
            int blanks = WIDTH - f_width;
            snprintf(buffer, sizeof(buffer), "M%*s%0*.*f", blanks, "", f_width, precision, f);
            printf("|%s| (b = %d; w = %d; p = %d)\n", buffer, blanks, f_width, precision);
            //printf("|%s|\n", buffer);
        }
    }
    return 0;
}

您是否尝试搜索printf?它的格式字符串将与snprintf的格式字符串相同。是的,我有,没有签名:/i可能必须手动添加空格谢谢,问题现在非常清楚。感谢Stargateur将其格式设置得非常简洁。我只使用一个转换说明符进行搜索,为了避免手动添加,我认为不可能添加此0d空间只有一个。但是是的,你的解决方案看起来不错,但是我仍然不明白OP为什么要这个零。我同意前导零的一个是特殊的-没有解释的味道。是的,我不认为它可以用一个
%…f
说明符来完成,因为
0
修饰符输出一个或多个零到宽度,但是输出是wan它只是一个单一的
0
。但是,我们也没有说明如何表示0和1之间的值,也没有说明10.00或更大的值,也没有说明负值。也没有说明所需精度的范围,…这是对所请求的两个输出的解决方案-但它不是真正的通用解决方案。”您可能需要确定log10(f)要知道用什么来代替3,例如,“你们能详细说明一下吗?至于”(但你们想要010.2346还是10.2346?),我限制为2位数字,没有负片。0到1之间的值仍应打印00。我同意需要对精度==0的情况进行特殊处理。再次感谢。除非您详细说明需要打印的值的范围、这些值的外观、需要支持的精度范围以及负片会发生什么情况您的需求严重不足,因此不清楚是否需要使用
log10(f)
。但您可能会发现
3==(int)log10(f)+3
#include <stdio.h>

int main(void)
{
    enum { WIDTH = 9 };
    for (double f = 1.2345678E-7; f < 100.0; f *= 10.0)
    {
        for (int precision = 1; precision <= 6; precision++)
        {
            char buffer[32];
            int f_width = precision + 3;    // decimal point and 2 digits before
            int blanks = WIDTH - f_width;
            snprintf(buffer, sizeof(buffer), "M%*s%0*.*f", blanks, "", f_width, precision, f);
            printf("|%s| (b = %d; w = %d; p = %d)\n", buffer, blanks, f_width, precision);
            //printf("|%s|\n", buffer);
        }
    }
    return 0;
}
|M     00.0| (b = 5; w = 4; p = 1)
|M    00.00| (b = 4; w = 5; p = 2)
|M   00.000| (b = 3; w = 6; p = 3)
|M  00.0000| (b = 2; w = 7; p = 4)
|M 00.00000| (b = 1; w = 8; p = 5)
|M00.000000| (b = 0; w = 9; p = 6)
|M     00.0| (b = 5; w = 4; p = 1)
|M    00.00| (b = 4; w = 5; p = 2)
|M   00.000| (b = 3; w = 6; p = 3)
|M  00.0000| (b = 2; w = 7; p = 4)
|M 00.00000| (b = 1; w = 8; p = 5)
|M00.000001| (b = 0; w = 9; p = 6)
|M     00.0| (b = 5; w = 4; p = 1)
|M    00.00| (b = 4; w = 5; p = 2)
|M   00.000| (b = 3; w = 6; p = 3)
|M  00.0000| (b = 2; w = 7; p = 4)
|M 00.00001| (b = 1; w = 8; p = 5)
|M00.000012| (b = 0; w = 9; p = 6)
|M     00.0| (b = 5; w = 4; p = 1)
|M    00.00| (b = 4; w = 5; p = 2)
|M   00.000| (b = 3; w = 6; p = 3)
|M  00.0001| (b = 2; w = 7; p = 4)
|M 00.00012| (b = 1; w = 8; p = 5)
|M00.000123| (b = 0; w = 9; p = 6)
|M     00.0| (b = 5; w = 4; p = 1)
|M    00.00| (b = 4; w = 5; p = 2)
|M   00.001| (b = 3; w = 6; p = 3)
|M  00.0012| (b = 2; w = 7; p = 4)
|M 00.00123| (b = 1; w = 8; p = 5)
|M00.001235| (b = 0; w = 9; p = 6)
|M     00.0| (b = 5; w = 4; p = 1)
|M    00.01| (b = 4; w = 5; p = 2)
|M   00.012| (b = 3; w = 6; p = 3)
|M  00.0123| (b = 2; w = 7; p = 4)
|M 00.01235| (b = 1; w = 8; p = 5)
|M00.012346| (b = 0; w = 9; p = 6)
|M     00.1| (b = 5; w = 4; p = 1)
|M    00.12| (b = 4; w = 5; p = 2)
|M   00.123| (b = 3; w = 6; p = 3)
|M  00.1235| (b = 2; w = 7; p = 4)
|M 00.12346| (b = 1; w = 8; p = 5)
|M00.123457| (b = 0; w = 9; p = 6)
|M     01.2| (b = 5; w = 4; p = 1)
|M    01.23| (b = 4; w = 5; p = 2)
|M   01.235| (b = 3; w = 6; p = 3)
|M  01.2346| (b = 2; w = 7; p = 4)
|M 01.23457| (b = 1; w = 8; p = 5)
|M01.234568| (b = 0; w = 9; p = 6)
|M     12.3| (b = 5; w = 4; p = 1)
|M    12.35| (b = 4; w = 5; p = 2)
|M   12.346| (b = 3; w = 6; p = 3)
|M  12.3457| (b = 2; w = 7; p = 4)
|M 12.34568| (b = 1; w = 8; p = 5)
|M12.345678| (b = 0; w = 9; p = 6)