如何大量插入空格以使其更具可读性?

jok*_*oon 4 c++ string numbers

我想到了这一点,因为在stackoverflow上提供的其他示例在C#中

string number_fmt(ulong n)
{
    // cout << "(" << n << ")" << endl;
    char s[128];
    sprintf(s, "%lu", n);
    string r(s);
    reverse(r.begin(), r.end());
    int space_inserted = 0;
    size_t how_many_spaces = r.length() / 3;

    if(r.length() % 3 != 0)
        how_many_spaces += 1;

    for(int i = 1; i < how_many_spaces; ++i)
    {
        r.insert(3 * i + space_inserted, " ");
        space_inserted += 1;
    }
    reverse(r.begin(), r.end());

    return r;
}
Run Code Online (Sandbox Code Playgroud)

您知道更好的解决方案吗?

Rob*_*obᵩ 5

我不知道“更好”,但是此版本使用std::locale,等等。

#include <iostream>
#include <locale>
#include <sstream>

template<class Char>
class MyFacet : public std::numpunct<Char> {
public:
  std::string do_grouping() const { return "\3"; }
  Char do_thousands_sep() const { return ' '; }
};

std::string number_fmt(unsigned long n)
{
  std::ostringstream oss;
  oss.imbue(std::locale(oss.getloc(), new MyFacet<char>));
  oss << n;
  return oss.str();
}

int main() {
  std::cout << number_fmt(123456789) << "\n";
}
Run Code Online (Sandbox Code Playgroud)


编辑:当然,如果您的最终目标是在上打印这些值ostream,则可以完全跳过将其存储的操作string

#include <iostream>
#include <locale>
#include <sstream>
#include <cwchar>

template <class Char>
class MyFacet : public std::numpunct<Char> {
public:
  std::string do_grouping() const { return "\3"; }
  Char do_thousands_sep() const { return ' '; }
};

int main(int ac, char **av) {
  using std::locale;
  using std::cout;

  // Show how it works to start with
  cout << 123456789 << "\n";

  // Switch it to spacey mode
  locale oldLoc =
    cout.imbue(locale(cout.getloc(), new MyFacet<char>));

  // How does it work now?
  cout << 456789123 << "\n";

  // You probably want to clean up after yourself
  cout.imbue(oldLoc);

  // Does it still work?
  cout << 789123456 << "\n";
}
Run Code Online (Sandbox Code Playgroud)


Set*_*gie 2

这个是不同的,但更好是主观的。我认为它的作用非常简洁明了:

string number_fmt(unsigned long long n, char sep = ',') {
    stringstream fmt;
    fmt << n;
    string s = fmt.str();
    s.reserve(s.length() + s.length() / 3);

    // loop until the end of the string and use j to keep track of every
    // third loop starting taking into account the leading x digits (this probably
    // can be rewritten in terms of just i, but it seems more clear when you use
    // a seperate variable)
    for (int i = 0, j = 3 - s.length() % 3; i < s.length(); ++i, ++j)
        if (i != 0 && j % 3 == 0)
            s.insert(i++, 1, sep);

    return s;
}
Run Code Online (Sandbox Code Playgroud)

使用它就像

cout << number_fmt(43615091387465) << endl;
Run Code Online (Sandbox Code Playgroud)

印刷

43,615,091,387,465
Run Code Online (Sandbox Code Playgroud)

  • 这是一个坏主意。流上的本地对象不仅已经做到了这一点,而且在实现方式上也更加灵活。还可以使用您输入/输出的对称本地对象(即 ir 将用逗号打印并用逗号读回。此外,通过使用本地,您可以获得本地特定的打印数字,并且不限于特定样式(在此案例欧洲-英国)。 (2认同)