snprintf以指定的宽度和指定的填充数字和指定的精度浮动

时间:2018-01-01 08:30:50

标签: c c99

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

M    01.23
M  01.2345

空间取决于可变精度。

我目前的代码是:

snprintf(buf, 10, "M%02.*f", precision, f);  

但是输出没有右对齐 - > |M01.234 |

有没有办法得到我想要的东西?

1 个答案:

答案 0 :(得分:3)

您还需要通过另一个*指定总数位。你还需要一个更大的缓冲区 - 一个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;
}

输出:

|M    01.23|
|M  01.2346|

9 - (precision+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;
}

输出:

|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)