整数を取り、カンマでフォーマットされたその整数のstd::string
を返すメソッドを書きたいです。
宣言例:
std::string FormatWithCommas(long value);
使用例:
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"
カンマでstring
として数値をフォーマットするC++の方法は何ですか?
(ボーナスはdouble
sも処理します。)
つかいます - 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();
}
免責事項:移植性が問題になる可能性があるため、""
合格
Jacobが提案したように、imbue
で""
ロケール-ただし、これはシステムのデフォルトを使用しますが、これはコンマを取得することを保証しません。 (システムのデフォルトのロケール設定に関係なく)コンマを強制する場合は、独自の numpunct
ファセットを指定することで実行できます。例えば:
#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;
}
次の答えは他の答えよりも簡単だと思います。
string numWithCommas = to_string(value);
int insertPosition = numWithCommas.length() - 3;
while (insertPosition > 0) {
numWithCommas.insert(insertPosition, ",");
insertPosition-=3;
}
これにより、数字の文字列にカンマがすばやく正しく挿入されます。
上記の回答に基づいて、私はこのコードになりました:
#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();
}
これはかなり古い学校です。別の文字列バッファーのインスタンス化を避けるために、大きなループで使用します。
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)?"":",");
}
}
Qtを使用している場合、次のコードを使用できます。
const QLocale & cLocale = QLocale::c();
QString resultString = cLocale.toString(number);
また、#include <QLocale>
を追加することを忘れないでください。
それをより柔軟にするために、カスタムの千文字列とグループ化文字列でファセットを構築できます。これにより、実行時に設定できます。
#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;
}