Подтвердить что ты не робот

С++: номер формата с запятыми?

Я хочу написать метод, который примет целое число и вернет 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 с запятыми?

(Бонус должен был бы обрабатывать double.)

4b9b3361

Ответ 1

Используйте std::locale с 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();
}

Отказ от ответственности: Переносимость может быть проблемой, и вы должны, вероятно, посмотреть, какой язык используется при передаче ""

Ответ 2

Вы можете сделать, как предложил Якоб, и 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;
}

Ответ 3

Я считаю следующий ответ более простым, чем другие:

string numWithCommas = to_string(value);
int insertPosition = numWithCommas.length() - 3;
while (insertPosition > 0) {
    numWithCommas.insert(insertPosition, ",");
    insertPosition-=3;
}

Это быстро и корректно вставляет запятые в строку цифр.

Ответ 4

основываясь на ответах выше, я закончил с этим кодом:

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

Ответ 5

Если вы используете Qt, вы можете использовать этот код:

const QLocale & cLocale = QLocale::c();
QString resultString = cLocale.toString(number);

Кроме того, не забудьте добавить #include <QLocale>.

Ответ 6

Это довольно старая школа, я использую ее в больших циклах, чтобы избежать создания экземпляра другого строкового буфера.

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)?"":",");
    }
}

Ответ 7

Чтобы сделать его более гибким, вы можете построить фасет с помощью настраиваемых тысяч сегментов и группировки. Таким образом вы можете установить его во время выполнения.

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