我有一个带有重载运算符<<的简单类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;
}
我感兴趣的是某种最简单的解决方案。
答案 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();
}