如何在Windows上的C语言中为双精度数添加千位分隔符?

far*_*dve 5 c windows double separator

我使用MPFR库对大数字进行计算,但也返回小数点后8位数字的双精度数。

我将数字mpfr_sprintf转换为char数组,以确保精度或任何功能都不会丢失。一切都很好,除了我在文档中没有找到任何千位分隔符选项(否则我错过了)。

给定一个诸如20043.95381376之类的数字,我希望将其表示为20,043.95381376,以提高可读性。

或数字164992818.48075795164,992,818.48075795

我读到有关应加到printf / sprintf中的撇号,但这似乎是UNIX / POSIX,并且我是Windows用户。

由于在内部我将数字打印为字符串,所以我认为我可以做的是编写一个自定义实现,该实现将根据数字自动添加逗号(> 1000> 10000> 100000,依此类推),但随后我意识到像strncpy这样的函数或strcpy将基本上替换,而不是将逗号添加到所需位置。这就是我回到如何做的第一件事。

我该怎么做?

net*_*der 3

您需要实现将双精度值转换为字符串并检查该字符串的每个字符,然后将其与分隔符一起复制到输出字符串。

像这样的东西:

#include <stdio.h>
#include <string.h>

int thousandsep(double in, char* out_str, size_t out_len, unsigned int precision) {
    char in_str[128], int_str[128], format[32];
    size_t dlen, mod, i, j;
    int c;

    snprintf(format, sizeof format, "%%.%df", precision);
    snprintf(in_str, sizeof in_str, format, in);
    snprintf(int_str, sizeof int_str, "%d", (int)in);

    dlen = strlen(in_str);
    mod = strlen(int_str) % 3;
    c = (mod == 0) ? 3 : mod;

    for (i=0, j=0; i<dlen; i++, j++, c--) {
        if (j >= out_len - 1) {
            /* out_str is too small */
            return -1;
        }

        if (in_str[i] == '.') {
            c = -1;
        } else if (c == 0) {
            out_str[j++] = ',';
            c = 3;
        }

        out_str[j] = in_str[i];
    }
    out_str[j] = '\0';

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

char out_str[64];

if (thousandsep(20043.95381376, out_str, sizeof out_str, 8) == 0)
    printf("%s\n", out_str);       /* 20,043.95381376 */

if (thousandsep(164992818.48075795, out_str, sizeof out_str, 8) == 0)
    printf("%s\n", out_str);       /* 164,992,818.48075795 */

if (thousandsep(1234567.0, out_str, sizeof out_str, 0) == 0)
    printf("%s\n", out_str);       /* 1,234,567 */
Run Code Online (Sandbox Code Playgroud)

注意:我假设如果您使用的是 Windows,则可能正在使用 MSVC,因此该解决方案应该适用于 C89 编译器。