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

时间:2010-04-15 19:29:09

标签: c++

我有一个带有重载运算符<<的简单类Currency。我不知道如何将数字与每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;
}

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

4 个答案:

答案 0 :(得分:15)

这可以通过facet来完成

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
}

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

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

答案 1 :(得分:7)

一种可能性是使用locales

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

答案 2 :(得分:2)

struct Currency {
  static char const sep = ' ';
  static int const group_size = 3;

  Currency(int val, std::string unit)
  : val(val), unit(unit)
  {}

  friend std::ostream& operator<<(std::ostream& out, Currency const& v) {
    // currently ignores stream width and fill
    std::ostringstream ss;
    bool const neg = v.val < 0;
    int const val = (neg ? -v.val : v.val);
    if (neg) out << '-';
    ss << val;
    std::string const s = ss.str();
    std::string::size_type n = s.size() % v.group_size;
    if (n) out << s.substr(0, n);
    for (; n < s.size(); n += v.group_size) {
      out << sep << s.substr(n, v.group_size);
    }
    out << ' ' << v.unit;
    return out;
  }

private:
  int val;
  std::string unit;
};

如果要使用逗号等自定义每个对象,可以使sep和group_size成为非静态成员(如果是这样,请将它们设为私有并在ctor中初始化,可能使用默认参数值。)您还可以使用traits类控制输出格式。

语言环境还通过moneypunct方面支持货币格式。

答案 3 :(得分:-1)

#include <iostream>

#include <sstream>

#include <cstdlib>

#define GROUP_SEP ','

#define GROUP_SIZE 3

using namespace std;

string  output_formatted_string(long long num);


int main() { 

    string temp;

    cout << "Enter a large number:  ";

    getline(cin, temp);

    long long num = atoll(temp.c_str());

    string output = output_formatted_string(num);


    cout << output << endl;

    return 0;

    }

    string output_formatted_string(long long num)

    { 

    stringstream temp, out;

    temp << num;

    string s = temp.str();


    int n = s.size() % GROUP_SIZE;

    int i = 0;

    if(n>0 && s.size() > GROUP_SIZE)

      {

        out << s.substr(i, n) << GROUP_SEP;

        i += n;

      }


    n = s.size() / GROUP_SIZE - 1;

    while(n-- > 0)
         {

        out << s.substr(i, GROUP_SIZE) << GROUP_SEP;

        i += GROUP_SIZE;         
}

    out << s.substr(i);

    return out.str();

    }