如何打印一个空格为千分隔的数字?

Krz*_*ter 8 c++

我有一个简单的类货币与重载运算符<<.我不知道如何将数字与空格每3位数分开,所以看起来像是:"1 234 567 ISK".

#include <cstdlib>
#include <iostream>

using namespace std;

class Currency
{
    int val;
    char curr[4];

    public:
    Currency(int _val, const char * _curr)
    {
        val = _val;
        strcpy(curr, _curr);
    }

    friend ostream & operator<< (ostream & out, const Currency & c);
};

ostream & operator<< (ostream & out, const Currency & c)
{
    out << c.val<< " " << c.curr;
    return out;
}

int main(int argc, char *argv[])
{
    Currency c(2354123, "ISK");
    cout << c;
}
Run Code Online (Sandbox Code Playgroud)

我感兴趣的是某种最简单的解决方案.

Joh*_*itb 15

这可以通过方面来完成

struct myseps : numpunct<char> { 
   /* use space as separator */
   char do_thousands_sep() const { return ' '; } 

   /* digits are grouped by 3 digits each */
   string do_grouping() const { return "\3"; }
};

int main() {
  std::cout.imbue(std::locale(std::locale(), new myseps));
  std::cout << 10000; // 10 000
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以编写自己的循环代码

void printGrouped(ostream &out, int n) {
  if(n < 0) {
    out << "-";
    return printGrouped(out, -n);
  }

  if(n < 1000) {
    out << n;
  } else {
    printGrouped(out, n / 1000);
    out << " " << setw(3) << setfill('0') << (n % 1000);
  }
}

ostream & operator<< (ostream & out, const Currency & c) {
    printGrouped(out, c.val);
    out << " " << c.curr;
    return out;
}
Run Code Online (Sandbox Code Playgroud)

  • @wilhelmtell我故意使用`locale("")`因为根据TC++ PL中stroustrup的locale附录,它使用"用户首选的语言环境"而C++标准说有效参数构成"C"和""(i怀疑""应该使用一些环境变量?).现在更改为默认构造函数.有人知道OSX上发生了什么,它不起作用? (2认同)

Unc*_*ens 7

一种可能性是为此使用区域设置.

#include <locale>
#include <string>
#include <cstddef>

class SpaceSeparator: public std::numpunct<char>
{
public:
    SpaceSeparator(std::size_t refs): std::numpunct<char>(refs) {}
protected:
    char do_thousands_sep() const { return ' '; }
    std::string do_grouping() const { return "\03"; }
};

//...    
ostream & operator<< (ostream & out, const Currency & c)
{
    SpaceSeparator facet(1); //1 - don't delete when done
    std::locale prev = out.imbue(std::locale(std::locale(), &facet));
    out << c.val<< " " << c.curr;
    out.imbue(prev);  //restore previous locale
    return out;
}
Run Code Online (Sandbox Code Playgroud)