How to print number with space as thousands separator?

I have a simple class currency with an overloaded operator <. I donโ€™t know how I can separate the number with spaces every 3 digits, so it looks like this: โ€œ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; } 

What interests me is somehow the simplest solution for this particular situation.

+8
c ++
Apr 15 '10 at 19:29
source share
4 answers

This can be done using faces.

 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 } 

Alternatively, you can program your own loop

 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; } 
+15
Apr 15 '10 at 20:00
source share

You can use locales for this.

 #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; } 
+7
Apr 15 '10 at 20:15
source share
 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; }; 

Non-static members sep and group_size can be made if you want to configure each object with a comma, etc. (If so, make them private and initialize in ctor, possibly with default parameter values.) You can also use a class class that controls output formatting.

Locales also support currency formatting across the moneypunct side.

+2
Apr 15 '10 at 19:59
source share
 #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(); } 
-one
Apr 01 2018-12-12T00:
source share



All Articles