Is there a built-in function that comma-separates a number in C, C++, or JavaScript? [closed]
Asked Answered
F

6

3

Given a number 12456789, I need to output 12,456,789 without much coding. Are there any built-in functions in either C, C++, or JavaScript I can use to do that?

Fernanda answered 13/8, 2010 at 17:56 Comment(0)
V
1

I found this little javascript function that would work (source):

function addCommas(nStr){
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}
Viticulture answered 13/8, 2010 at 18:10 Comment(1)
Thanks, I found the same thing learning from TheUndeadFish.Fernanda
P
24

Yes this can be done automatically in C++ by setting the correct facet on the locale.

#include <iostream>
#include <locale>
#include <string>


template<typename CharT>
struct Sep : public std::numpunct<CharT>
{
    virtual std::string do_grouping()      const   {return "\003";}
};

int main()
{
    std::cout.imbue(std::locale(std::cout.getloc(), new Sep <char>()));

    std::cout << 123456789 << "\n";

}

Note: The C-locale (The locale used when your application does not specifically set one) does not use a thousands separator. If you set the locale of your application to a specific language then it will pick up the languages specific method of grouping (without having to do anything fancy like the above). If you want to set the locale to what your machines current language settings (as defined by the OS) rather than a specific locale then use "" (empty string) as the locale.

So to set the locale based on your OS specific settings:

int main()
{
    std::cout.imbue(std::locale(""));

    std::cout << 123456789 << "\n";
}
Pal answered 13/8, 2010 at 18:1 Comment(1)
better than the accepted answer here https://mcmap.net/q/238597/-format-number-with-commas-in-c, which does not work without extensive study and jiggering.Teratism
S
15

In C++ you'd typically use something like this:

std::locale loc("");
std::cout.imbue(loc);

std::cout << 1234567;

The locale with an empty name like this uses won't necessarily format the number exactly as you've specified above. Instead, it picks up the locale from the rest of the system, and formats appropriately, so for me (with my system set up for the US) it would produce "1,234,567", but if the system was set up for (most parts of) Europe, it would produce "1.234.567" instead.

Submersible answered 13/8, 2010 at 18:20 Comment(3)
+1 can't get any easier than this :) I like C++ ^^Postiche
This is not a precise answer, it depends on the default locale on the system. std::locale loc("en_US.UTF-8"); may be more robust.Centrum
@prehistoricpenguin: I suppose that depends on how you define "robust". If you mean "may sometimes do something desirable, but other times fail completely", then yeah, that would be accurate (e.g., fails with minGW). But the point of the answer is that most of the time you should be trying to tailor the output to the user's desires, which is what the nameless locale tries to provide.Submersible
L
3

In some C compiler implementations, and extension is provided for the printf familiy of functions such that a single-quote/apostrophe character used as a modifier in a numeric format specifier will perform 'thousands grouping':

#include <stdio.h>
#include <locale.h>

int main(void)
{
    printf( "%'d\n", 1234567);

    setlocale(LC_NUMERIC, "en_US");
    printf( "%'d\n", 1234567);

    return 0;
}

will produce (with GCC 4.4.1 anyway):

1234567
1,234,567

Unfortunately, this extension isn't particularly widely supported.

Lehet answered 13/8, 2010 at 18:12 Comment(0)
H
2

// Another javascript method, works on numbers

Number.prototype.withCommas= function(){    
    return String(this).replace(/\B(?=(?:\d{3})+(?!\d))/g,',')
}

var n=12456789.25;
alert(n.withCommas());

/* returned value: (String) 12,456,789.25 */

Hodeida answered 13/8, 2010 at 20:24 Comment(0)
A
2

For C++, you can try:

std::locale get_numpunct_locale(std::locale locale = std::locale(""))
{
#if defined(_MSC_VER) && defined(_ADDFAC) && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 403)
    // Workaround for older implementations
    std::_ADDFAC(locale, new std::numpunct<char>());
    return locale;
#else
    return std::locale(locale, new std::numpunct<TCHAR>());
#endif
}

template<class T>
std::string nformat(T value)
{
    std::ostringstream ss;
    ss.imbue(get_numpunct_locale());
    ss << value;
    return ss.str();
}
Astray answered 7/9, 2012 at 21:20 Comment(8)
I am on VS19 and I am having an error that says "error C2039: _ADDFAC: is not a member of std". Do you know why?Imitative
@SandraK: What is your _CPPLIB_VER?Astray
Not sure, how do I check?Imitative
@SandraK: #include <iostream> int main() { std::cout << _CPPLIB_VER << std::endl; }Astray
Ah ... 650 :D ..Imitative
@SandraK: Yeah, so that means you removed the _CPPLIB_VER < 403 check I had put in there!Astray
Well dammit, I am that stupid :D Thanks!Imitative
@SandraK: No problem!Astray
V
1

I found this little javascript function that would work (source):

function addCommas(nStr){
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}
Viticulture answered 13/8, 2010 at 18:10 Comment(1)
Thanks, I found the same thing learning from TheUndeadFish.Fernanda

© 2022 - 2024 — McMap. All rights reserved.