I want to write a method that will take an integer and return a std::string
of that integer formatted with commas.
Example declaration:
std::string FormatWithCommas(long value);
Example usage:
std::string result = FormatWithCommas(7800);
std::string result2 = FormatWithCommas(5100100);
std::string result3 = FormatWithCommas(201234567890);
// result = "7,800"
// result2 = "5,100,100"
// result3 = "201,234,567,890"
What is the C++ way of formatting a number as a string
with commas?
(Bonus would be to handle double
s as well.)
Use std::locale
with std::stringstream
#include <iomanip>
#include <locale>
template<class T>
std::string FormatWithCommas(T value)
{
std::stringstream ss;
ss.imbue(std::locale(""));
ss << std::fixed << value;
return ss.str();
}
Disclaimer: Portability might be an issue and you should probably look at which locale is used when ""
is passed
You can do as Jacob suggested, and imbue
with the ""
locale - but this will use the system default, which does not guarantee that you get the comma. If you want to force the comma (regardless of the systems default locale settings) you can do so by providing your own numpunct
facet. For example:
#include <locale>
#include <iostream>
#include <iomanip>
class comma_numpunct : public std::numpunct<char>
{
protected:
virtual char do_thousands_sep() const
{
return ',';
}
virtual std::string do_grouping() const
{
return "\03";
}
};
int main()
{
// this creates a new locale based on the current application default
// (which is either the one given on startup, but can be overriden with
// std::locale::global) - then extends it with an extra facet that
// controls numeric output.
std::locale comma_locale(std::locale(), new comma_numpunct());
// tell cout to use our new locale.
std::cout.imbue(comma_locale);
std::cout << std::setprecision(2) << std::fixed << 1000000.1234;
}
I consider the following answer to be easier than the others:
string numWithCommas = to_string(value);
int insertPosition = numWithCommas.length() - 3;
while (insertPosition > 0) {
numWithCommas.insert(insertPosition, ",");
insertPosition-=3;
}
This will quickly and correctly insert commas into your string of digits.
based on the answers above, I ended up with this code:
#include <iomanip>
#include <locale>
template<class T>
std::string numberFormatWithCommas(T value){
struct Numpunct: public std::numpunct<char>{
protected:
virtual char do_thousands_sep() const{return ',';}
virtual std::string do_grouping() const{return "\03";}
};
std::stringstream ss;
ss.imbue({std::locale(), new Numpunct});
ss << std::setprecision(2) << std::fixed << value;
return ss.str();
}
If you are using Qt, you can use this code:
const QLocale & cLocale = QLocale::c();
QString resultString = cLocale.toString(number);
Also, do not forget to add #include <QLocale>
.
This is pretty old school, I use it in large loops to avoid instantiating another string buffer.
void tocout(long a)
{
long c = 1;
if(a<0) {a*=-1;cout<<"-";}
while((c*=1000)<a);
while(c>1)
{
int t = (a%c)/(c/1000);
cout << (((c>a)||(t>99))?"":((t>9)?"0":"00")) << t;
cout << (((c/=1000)==1)?"":",");
}
}
To make it more flexible, you could construct the facet with a custom thousands sep and grouping string. This way you can set it at runtime.
#include <locale>
#include <iostream>
#include <iomanip>
#include <string>
class comma_numpunct : public std::numpunct<char>
{
public:
comma_numpunct(char thousands_sep, const char* grouping)
:m_thousands_sep(thousands_sep),
m_grouping(grouping){}
protected:
char do_thousands_sep() const{return m_thousands_sep;}
std::string do_grouping() const {return m_grouping;}
private:
char m_thousands_sep;
std::string m_grouping;
};
int main()
{
std::locale comma_locale(std::locale(), new comma_numpunct(',', "\03"));
std::cout.imbue(comma_locale);
std::cout << std::setprecision(2) << std::fixed << 1000000.1234;
}
来源:https://stackoverflow.com/questions/7276826/c-format-number-with-commas