Je veux écrire une méthode qui prendra un entier et renverra un std::string
de cet entier formaté avec des virgules.
Exemple de déclaration:
std::string FormatWithCommas(long value);
Exemple d'utilisation:
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"
Quelle est la méthode C++ pour formater un nombre sous la forme string
avec des virgules?
(Le bonus serait de gérer double
s aussi.)
Utilisez std::locale
avec 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: La portabilité pourrait être un problème et vous devriez probablement regarder quel paramètre régional est utilisé lorsque ""
est passé
Vous pouvez faire ce que Jacob a suggéré, et imbue
avec les paramètres régionaux ""
- mais cela utilisera la valeur par défaut du système, ce qui ne garantit pas que vous obtenez la virgule. Si vous souhaitez forcer la virgule (quels que soient les paramètres régionaux par défaut du système), vous pouvez le faire en fournissant votre propre numpunct
facet. Par exemple:
#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;
}
Je considère que la réponse suivante est plus facile que les autres:
string numWithCommas = to_string(value);
int insertPosition = numWithCommas.length() - 3;
while (insertPosition > 0) {
numWithCommas.insert(insertPosition, ",");
insertPosition-=3;
}
Cela va rapidement et correctement insérer des virgules dans votre chaîne de chiffres.
sur la base des réponses ci-dessus, j'ai fini avec ce 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();
}
Ceci est assez vieux école, je l'utilise dans les grandes boucles pour éviter d'instancier un autre tampon de chaîne.
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)?"":",");
}
}
Si vous utilisez Qt, vous pouvez utiliser ce code:
const QLocale & cLocale = QLocale::c();
QString resultString = cLocale.toString(number);
De plus, n'oubliez pas d'ajouter #include <QLocale>
.
Pour le rendre plus flexible, vous pouvez construire la facette avec une chaîne de milliers et une chaîne de regroupement personnalisées .
#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;
}