How can I add a thousands separator to a double in C on Windows?

You need your implementation to convert the double value to string and examine each character of that string, then copy it to an output string along with the separators.

Something like this:

#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;
}

Then use it like so:

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 */

Note: I assumed that if you're on Windows, you may be using MSVC so this solution should be working on C89 compilers.


GetNumberFormatEx will take the plain string version of the number and format it with the grouping separators, appropriate decimal point, etc. Pass LOCALE_NAME_USER_DEFAULT as the locale, and it will be in the format that the user prefers.

If you need to override one of the settings (like the precision), you can populate a NUMBERFMT struct with the defaults and then change the fields you need to control.